/* See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * Esri Inc. licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.esri.gpt.control.arcims; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; import java.security.Principal; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Provides a basic proxy servlet for ArcXML requests */ public class ServletConnectorProxy extends HttpServlet { // class variables // ============================================================= private static Logger LOGGER = Logger.getLogger(ServletConnectorProxy.class .getName()); // instance variables // ============================================================= private String _redirectURL = null; // properties ============================================================= // methods variables // ============================================================= /** * Loads initial parameters for the servlet * * @throws ServletException * if an exception occurs */ public void init() throws ServletException { this._redirectURL = this.getInitParameter("redirectURL"); } /** * Handles a GET request. <p/> The default behavior is the execute the doGet * method. * * @param request * the servlet request * @param response * the servlet response * @throws ServletException * @throws IOException * if an exception occurs */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* if(true){ doPost(request,response); return; }*/ /*if(!_redirectURL.startsWith("http")) setURL(request); response.sendRedirect(_redirectURL + "?" + request.getQueryString());*/ Principal p = request.getUserPrincipal(); if(p != null){ LOGGER.finer("UserName : " + p.getName()); } LOGGER.finer("Query string=" + request.getQueryString()); if ("ping".equalsIgnoreCase(request.getParameter("Cmd"))) { response.getWriter().write("IMS v9.3.0"); } else if ("ping".equalsIgnoreCase(request.getParameter("cmd"))) { response.getWriter().write("IMS v9.3.0"); } else if ("getVersion".equalsIgnoreCase(request.getParameter("Cmd"))) { response.getWriter().write("Version=9.3.0\nBuild_Number=514.2159"); } else { response.sendError(HttpServletResponse.SC_NOT_FOUND); } } /** * Handles a POST request. * * @param request * the servlet request * @param response * the servlet response * @throws ServletException * @throws IOException * if an exception occurs */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if(!_redirectURL.startsWith("http")) setURL(request); Principal p = request.getUserPrincipal(); if(p != null){ LOGGER.finer("UserName : " + p.getName()); } executeProxy(request, response); } /** * Sets redirect url to next door GPT application * * @param request * the servlet request */ private void setURL(HttpServletRequest request) { StringBuffer sb = new StringBuffer(); sb.append("http://") .append(request.getServerName()).append(":") .append(request.getServerPort()).append(_redirectURL); _redirectURL = sb.toString(); LOGGER.finer(_redirectURL); } /** * Communicates with redirect url and works as a transparent proxy * * @param request * the servlet request * @param response * the servlet response * @throws IOException * if an exception occurs */ private void executeProxy(HttpServletRequest request, HttpServletResponse response) throws IOException { HttpURLConnection httpCon = null; URL redirectURL = null; InputStream input = null; OutputStream output = null; InputStream proxyInput = null; OutputStream proxyOutput = null; try { input = request.getInputStream(); output = response.getOutputStream(); String sQueryStr = request.getQueryString(); String sAuthorization = request.getHeader("Authorization"); String requestBody = readInputCharacters(input); String requestMethod = request.getMethod(); String contentType = request.getContentType(); String encoding = request.getCharacterEncoding(); LOGGER.finer(" Request method = " + requestMethod); LOGGER.finer(" Query string = " + sQueryStr); LOGGER.finer(" Authorization header =" + sAuthorization); LOGGER.finer(" Character Encoding = " + encoding); LOGGER.finer(" The redirect URL is " + this._redirectURL + "?" + sQueryStr); redirectURL = new URL(this._redirectURL + "?" + sQueryStr); httpCon = (HttpURLConnection) redirectURL.openConnection(); httpCon.setDoInput(true); httpCon.setDoOutput(true); httpCon.setUseCaches(false); httpCon.setRequestMethod(requestMethod); httpCon.setRequestProperty("Content-type", contentType); if (sAuthorization != null) { httpCon.addRequestProperty("Authorization", sAuthorization); } proxyOutput = httpCon.getOutputStream(); send(requestBody, proxyOutput); String authenticateHdr = httpCon.getHeaderField("WWW-Authenticate"); if(authenticateHdr != null){ LOGGER.finer(" WWW-Authenticate : " + authenticateHdr); response.setHeader("WWW-Authenticate", authenticateHdr); } LOGGER.finer(" Response Code : " + httpCon.getResponseCode()); if ((httpCon.getResponseCode() == HttpURLConnection.HTTP_FORBIDDEN)){ response.sendError(HttpServletResponse.SC_FORBIDDEN); } else if((httpCon.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED)) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } else if((httpCon.getResponseCode() == HttpURLConnection.HTTP_INTERNAL_ERROR)) { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } else { proxyInput = httpCon.getInputStream(); send(proxyInput, output); } } catch (Exception e) { e.printStackTrace(); } finally { if (input != null) { input.close(); } if (output != null) { output.close(); } if (proxyInput != null) { proxyInput.close(); } if (proxyOutput != null) { proxyOutput.close(); } if (httpCon != null) { httpCon.disconnect(); } } } /** * Fully reads the characters from an InputStream. * * @param strm * the InputStream * @return the characters read * @throws IOException * if an exception occurs */ private String readInputCharacters(InputStream inputStream) throws IOException { StringBuffer sb = new StringBuffer(); InputStreamReader ir = null; BufferedReader br = null; try { char cbuf[] = new char[2048]; int n = 0; int nLen = cbuf.length; String sEncoding = "UTF-8"; ir = new InputStreamReader(inputStream, sEncoding); br = new BufferedReader(ir); while ((n = br.read(cbuf, 0, nLen)) > 0) { sb.append(cbuf, 0, n); } } finally { try { if (br != null) br.close(); } catch (Exception ef) { } try { if (ir != null) ir.close(); } catch (Exception ef) { } } return sb.toString(); } /** * Sends request to the opened HTTP connection. * * @param requestBody * as string * @param output * to stream the data * * @throws java.io.IOException * if sending data failed */ private void send(String requestBody, OutputStream output) throws IOException { PrintWriter outputWriter = null; try { outputWriter = new PrintWriter(output); outputWriter.write(requestBody); outputWriter.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (output != null) { output.close(); } } catch (Exception ef) { ef.printStackTrace(); } } } /** * Sends request to the opened HTTP connection. * * @param input * data as stream * @param outputWriter * to send back response * * @throws java.io.IOException * if sending data failed */ private void send(InputStream input, PrintWriter outputWriter) throws IOException { try { outputWriter.write(readInputCharacters(input)); outputWriter.flush(); } catch (Exception e) { e.printStackTrace(); } } /** * Sends request to the opened HTTP connection. * * @param input * data as stream * @param output * output as stream * * @throws java.io.IOException * if sending data failed */ private void send(InputStream input, OutputStream output) throws IOException { PrintWriter outputWriter = null; try { outputWriter = new PrintWriter(output); outputWriter.write(readInputCharacters(input)); outputWriter.flush(); } catch (Exception e) { e.printStackTrace(); } finally { if (outputWriter != null) { outputWriter.close(); } } } }