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.http; 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 035public class 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 047 * client. 048 */ 049 public MasterRedirectServlet(InfoServer infoServer, String hostname) { 050 regionServerInfoPort = infoServer.getPort(); 051 regionServerHostname = hostname; 052 } 053 054 @Override 055 public void doGet(HttpServletRequest request, HttpServletResponse response) 056 throws ServletException, IOException { 057 String redirectHost = regionServerHostname; 058 if (redirectHost == null) { 059 redirectHost = request.getServerName(); 060 if (!Addressing.isLocalAddress(InetAddress.getByName(redirectHost))) { 061 LOG.warn("Couldn't resolve '" + redirectHost + "' as an address local to this node and '" 062 + MASTER_HOSTNAME_KEY + "' is not set; client will get an HTTP 400 response. If " 063 + "your HBase deployment relies on client accessible names that the region server " 064 + "process can't resolve locally, then you should set the previously mentioned " 065 + "configuration variable to an appropriate hostname."); 066 // no sending client provided input back to the client, so the goal host is just in the 067 // logs. 068 response.sendError(400, 069 "Request was to a host that I can't resolve for any of the network interfaces on " 070 + "this node. If this is due to an intermediary such as an HTTP load balancer or " 071 + "other proxy, your HBase administrator can set '" + MASTER_HOSTNAME_KEY 072 + "' to point to the correct hostname."); 073 return; 074 } 075 } 076 // TODO: this scheme should come from looking at the scheme registered in the infoserver's http 077 // server for the host and port we're using, but it's buried way too deep to do that ATM. 078 String redirectUrl = request.getScheme() + "://" + redirectHost + ":" + regionServerInfoPort 079 + request.getRequestURI(); 080 response.sendRedirect(redirectUrl); 081 } 082}