/** * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { out.println("<html>"); out.println("<head>"); out.println("<title>Low Level SecServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Low Level Security at " + request.getContextPath() + "</h1>"); out.println("<br>"); out.println("AuthType:[" + request.getAuthType() + "]"); out.println("<br>"); out.println("RemoteUser:[" + request.getRemoteUser() + "]"); out.println("<br>"); if (request.getUserPrincipal() != null) { out.println("UserPrincipal.Name:[" + request.getUserPrincipal().getName() + "]"); } else { out.println("no principal"); } out.println("</hr>"); out.println("</body>"); out.println("</html>"); } finally { out.close(); } }
@Override public String getAuthType() { HttpServletRequest request = (HttpServletRequest) getRequest(); String headerValue; headerValue = request.getHeader(headerPrefix + "AUTH_TYPE"); if (headerValue != null) { return headerValue; } else { return request.getAuthType(); } }
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain fc) throws IOException, ServletException { final HttpServletRequest r = (HttpServletRequest) request; final String remoteUser = r.getRemoteUser(); final String authType = r.getAuthType(); final Principal userPrincipal = r.getUserPrincipal(); if (remoteUser != null || authType != null || userPrincipal != null) { ((HttpServletResponse) response).sendRedirect(target); } else { fc.doFilter(request, response); } }
// Update the agent URL in the agent details if not already done private void updateAgentDetailsIfNeeded(HttpServletRequest pReq) { // Lookup the Agent URL if needed AgentDetails details = backendManager.getAgentDetails(); if (details.isInitRequired()) { synchronized (details) { if (details.isInitRequired()) { if (details.isUrlMissing()) { String url = getBaseUrl( NetworkUtil.sanitizeLocalUrl(pReq.getRequestURL().toString()), extractServletPath(pReq)); details.setUrl(url); } if (details.isSecuredMissing()) { details.setSecured(pReq.getAuthType() != null); } details.seal(); } } } }
/** * Returns a String with all basic request information in an HTML table. * * @return A String with all basic request information in an HTML table. */ public String getRequestInfo() { Map info = new TreeMap(); HttpServletRequest req = (HttpServletRequest) pageContext.getRequest(); info.put("authType", nullToString(req.getAuthType())); info.put("characterEncoding", nullToString(req.getCharacterEncoding())); info.put("contentLength", Integer.toString(req.getContentLength())); info.put("contentType", nullToString(req.getContentType())); info.put("contextPath", nullToString(req.getContextPath())); info.put("pathInfo", nullToString(req.getPathInfo())); info.put("protocol", nullToString(req.getProtocol())); info.put("queryString", nullToString(req.getQueryString())); info.put("remoteAddr", nullToString(req.getRemoteAddr())); info.put("remoteHost", nullToString(req.getRemoteHost())); info.put("remoteUser", nullToString(req.getRemoteUser())); info.put("requestURI", nullToString(req.getRequestURI())); info.put("scheme", nullToString(req.getScheme())); info.put("serverName", nullToString(req.getServerName())); info.put("serverPort", Integer.toString(req.getServerPort())); info.put("servletPath", nullToString(req.getServletPath())); return toHTMLTable("request properties", info); }
/** {@inheritDoc} */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest rqst = (HttpServletRequest) request; HttpServletResponse rsp = (HttpServletResponse) response; if (LOG.isDebugEnabled()) { StringBuilder b = new StringBuilder("Request from ") .append(rqst.getRemoteHost()) .append("/") .append(rqst.getRemoteAddr()) .append(":") .append(rqst.getRemotePort()); @SuppressWarnings("unchecked") Enumeration<String> e = rqst.getAttributeNames(); for (; e.hasMoreElements(); ) { String attribute = e.nextElement(); b.append("\n " + attribute + " => " + rqst.getAttribute(attribute)); } X509Certificate[] userCerts = (X509Certificate[]) rqst.getAttribute("javax.servlet.request.X509Certificate"); if (userCerts != null) for (X509Certificate cert : userCerts) b.append( "\n Client certificate Subject Name is " + cert.getSubjectX500Principal().getName()); b.append("\n The Scheme is " + rqst.getScheme()); b.append("\n The Auth Type is " + rqst.getAuthType()); b.append("\n The Path Info is " + rqst.getPathInfo()); b.append("\n The Translated Path Info is " + rqst.getPathTranslated()); b.append("\n The Context Path is " + rqst.getContextPath()); b.append("\n The Query String is " + rqst.getQueryString()); b.append("\n The Remote User is " + rqst.getRemoteUser()); b.append("\n The User Principal is " + rqst.getUserPrincipal()); b.append("\n The Request URI is " + rqst.getRequestURI()); b.append("\n The Request URL is " + rqst.getRequestURL()); b.append("\n The Servlet Path is " + rqst.getServletPath()); LOG.debug(b.toString()); } if (rqst.getScheme().equalsIgnoreCase("https")) { boolean isAuthorized = false; X509Certificate[] certs = (X509Certificate[]) rqst.getAttribute("javax.servlet.request.X509Certificate"); if (certs == null || certs.length == 0) { rsp.sendError(HttpServletResponse.SC_BAD_REQUEST, "No client SSL certificate received"); return; } for (X509Certificate cert : certs) { try { cert.checkValidity(); } catch (CertificateExpiredException e) { LOG.info("Received cert for " + cert.getSubjectX500Principal().getName() + " expired"); rsp.sendError(HttpServletResponse.SC_FORBIDDEN, "Certificate expired"); return; } catch (CertificateNotYetValidException e) { LOG.info( "Received cert for " + cert.getSubjectX500Principal().getName() + " is not yet valid"); rsp.sendError(HttpServletResponse.SC_FORBIDDEN, "Certificate is not yet valid"); return; } } String[] tokens = certs[0].getSubjectX500Principal().getName().split("\\s*,\\s*"); String userID = null; for (String s : tokens) { if (s.startsWith("CN=")) { userID = s; break; } } if (userID == null || userID.length() < 4) { LOG.info("Can't retrieve user ID from SSL certificate"); rsp.sendError( HttpServletResponse.SC_FORBIDDEN, "Can't retrieve user ID from SSL certificate"); return; } userID = userID.substring(3); String servletPath = rqst.getServletPath(); if (HFTP_PATTERN.matcher(servletPath).matches()) { // request is an HSFTP request if (FILEPATH_PATTERN.matcher(servletPath).matches()) { // file path as part of the URL isAuthorized = checkPath(userID, certs[0], rqst.getPathInfo() != null ? rqst.getPathInfo() : "/"); } else { // file path is stored in "filename" parameter isAuthorized = checkPath(userID, certs[0], rqst.getParameter("filename")); } } else if (RELOAD_PATTERN.matcher(servletPath).matches() && checkUser("Admin", certs[0])) { Configuration conf = new Configuration(false); conf.addResource("hdfsproxy-default.xml"); Map<String, Set<Path>> permsMap = getPermMap(conf); Map<String, Set<BigInteger>> certsMap = getCertsMap(conf); if (permsMap == null || certsMap == null) { LOG.warn("Permission files reloading failed"); rsp.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Permission files reloading failed"); return; } ProxyFilter.permsMap = permsMap; ProxyFilter.certsMap = certsMap; LOG.info("User permissions and user certs files reloaded"); rsp.setStatus(HttpServletResponse.SC_OK); return; } else if (CLEAR_PATTERN.matcher(servletPath).matches() && checkUser("Admin", certs[0])) { ProxyUgiManager.clearCache(); LOG.info("Ugi cache cleared"); rsp.setStatus(HttpServletResponse.SC_OK); return; } if (!isAuthorized) { rsp.sendError(HttpServletResponse.SC_FORBIDDEN, "Unauthorized access"); return; } // request is authorized, set ugi for servlets UnixUserGroupInformation ugi = ProxyUgiManager.getUgiForUser(userID); if (ugi == null) { LOG.info("Can't retrieve ugi for user " + userID); rsp.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Can't retrieve ugi for user " + userID); return; } rqst.setAttribute("authorized.ugi", ugi); } else { // http request, set ugi for servlets, only for testing purposes String ugi = rqst.getParameter("ugi"); rqst.setAttribute("authorized.ugi", new UnixUserGroupInformation(ugi.split(","))); } chain.doFilter(request, response); }
/** * Copy the HttpServletRequest content inside an AtmosphereRequest. By default the returned * AtmosphereRequest is not destroyable. * * @param request {@link HttpServletRequest} * @return an {@link AtmosphereRequest} */ public static final AtmosphereRequest cloneRequest( HttpServletRequest request, boolean loadInMemory, boolean copySession, boolean isDestroyable, boolean createSession) { Builder b; HttpServletRequest r; Cookie[] cs = request.getCookies(); Set<Cookie> hs = Collections.synchronizedSet(new HashSet()); if (cs != null) { for (Cookie c : cs) { hs.add(c); } } boolean isWrapped = false; if (AtmosphereRequestImpl.class.isAssignableFrom(request.getClass())) { b = AtmosphereRequestImpl.class.cast(request).b; isWrapped = true; } else { b = new Builder(); b.request(request); } HttpSession session = null; if (copySession) { session = request.getSession(createSession); if (session != null) { session = new FakeHttpSession(session); } else { session = new FakeHttpSession("", null, System.currentTimeMillis(), -1); } } b.servletPath(request.getServletPath()) .pathInfo(request.getPathInfo()) .contextPath(request.getContextPath()) .requestURI(request.getRequestURI()) .requestURL(request.getRequestURL().toString()) .method(request.getMethod()) .serverName(request.getServerName()) .serverPort(request.getServerPort()) .remoteAddr(request.getRemoteAddr()) .remoteHost(request.getRemoteHost()) .remotePort(request.getRemotePort()) .destroyable(isDestroyable) .cookies(hs) .session(session) .principal(request.getUserPrincipal()) .authType(request.getAuthType()) .isSSecure(request.isSecure()); if (loadInMemory) { String s = (String) attributeWithoutException(request, FrameworkConfig.THROW_EXCEPTION_ON_CLONED_REQUEST); boolean throwException = s != null && Boolean.parseBoolean(s); r = new NoOpsRequest(throwException); if (isWrapped) { load(b.request, b); } else { load(request, b); } b.request(r); } return isWrapped ? AtmosphereRequestImpl.class.cast(request) : b.build(); }
private void setEnvironment(ClientSocket stream, WriteStream ws, HttpServletRequest req) throws IOException { addHeader(stream, ws, "REQUEST_URI", req.getRequestURI()); addHeader(stream, ws, "REQUEST_METHOD", req.getMethod()); addHeader(stream, ws, "SERVER_SOFTWARE", "Resin/" + VersionFactory.getVersion()); addHeader(stream, ws, "SERVER_NAME", req.getServerName()); // addHeader(stream, ws, "SERVER_ADDR=" + req.getServerAddr()); addHeader(stream, ws, "SERVER_PORT", String.valueOf(req.getServerPort())); addHeader(stream, ws, "REMOTE_ADDR", req.getRemoteAddr()); addHeader(stream, ws, "REMOTE_HOST", req.getRemoteAddr()); // addHeader(stream, ws, "REMOTE_PORT=" + req.getRemotePort()); if (req.getRemoteUser() != null) addHeader(stream, ws, "REMOTE_USER", req.getRemoteUser()); else addHeader(stream, ws, "REMOTE_USER", ""); if (req.getAuthType() != null) addHeader(stream, ws, "AUTH_TYPE", req.getAuthType()); addHeader(stream, ws, "GATEWAY_INTERFACE", "CGI/1.1"); addHeader(stream, ws, "SERVER_PROTOCOL", req.getProtocol()); if (req.getQueryString() != null) addHeader(stream, ws, "QUERY_STRING", req.getQueryString()); else addHeader(stream, ws, "QUERY_STRING", ""); String scriptPath = req.getServletPath(); String pathInfo = req.getPathInfo(); WebApp webApp = (WebApp) req.getServletContext(); Path appDir = webApp.getAppDir(); String realPath = webApp.getRealPath(scriptPath); if (!appDir.lookup(realPath).isFile() && pathInfo != null) scriptPath = scriptPath + pathInfo; /* * FastCGI (specifically quercus) uses the PATH_INFO and PATH_TRANSLATED * for the script path. */ log.finer("STREAM file: " + webApp.getRealPath(scriptPath)); addHeader(stream, ws, "PATH_INFO", req.getContextPath() + scriptPath); addHeader(stream, ws, "PATH_TRANSLATED", webApp.getRealPath(scriptPath)); /* These are the values which would be sent to CGI. addHeader(stream, ws, "SCRIPT_NAME", req.getContextPath() + scriptPath); addHeader(stream, ws, "SCRIPT_FILENAME", app.getRealPath(scriptPath)); if (pathInfo != null) { addHeader(stream, ws, "PATH_INFO", pathInfo); addHeader(stream, ws, "PATH_TRANSLATED", req.getRealPath(pathInfo)); } else { addHeader(stream, ws, "PATH_INFO", ""); addHeader(stream, ws, "PATH_TRANSLATED", ""); } */ int contentLength = req.getContentLength(); if (contentLength < 0) addHeader(stream, ws, "CONTENT_LENGTH", "0"); else addHeader(stream, ws, "CONTENT_LENGTH", String.valueOf(contentLength)); ServletContext rootContext = webApp.getContext("/"); if (rootContext != null) addHeader(stream, ws, "DOCUMENT_ROOT", rootContext.getRealPath("/")); CharBuffer cb = new CharBuffer(); Enumeration e = req.getHeaderNames(); while (e.hasMoreElements()) { String key = (String) e.nextElement(); String value = req.getHeader(key); if (key.equalsIgnoreCase("content-length")) addHeader(stream, ws, "CONTENT_LENGTH", value); else if (key.equalsIgnoreCase("content-type")) addHeader(stream, ws, "CONTENT_TYPE", value); else if (key.equalsIgnoreCase("if-modified-since")) { } else if (key.equalsIgnoreCase("if-none-match")) { } else if (key.equalsIgnoreCase("authorization")) { } else if (key.equalsIgnoreCase("proxy-authorization")) { } else addHeader(stream, ws, convertHeader(cb, key), value); } }
public String getAuthType() { return request.getAuthType(); }
private String[] makeEnv(final HttpServletRequest req, final ProjectControl project) { final EnvList env = new EnvList(_env); final int contentLength = Math.max(0, req.getContentLength()); // These ones are from "The WWW Common Gateway Interface Version 1.1" // env.set("AUTH_TYPE", req.getAuthType()); env.set("CONTENT_LENGTH", Integer.toString(contentLength)); env.set("CONTENT_TYPE", req.getContentType()); env.set("GATEWAY_INTERFACE", "CGI/1.1"); env.set("PATH_INFO", req.getPathInfo()); env.set("PATH_TRANSLATED", null); env.set("QUERY_STRING", req.getQueryString()); env.set("REMOTE_ADDR", req.getRemoteAddr()); env.set("REMOTE_HOST", req.getRemoteHost()); env.set("HTTPS", req.isSecure() ? "ON" : "OFF"); // The identity information reported about the connection by a // RFC 1413 [11] request to the remote agent, if // available. Servers MAY choose not to support this feature, or // not to request the data for efficiency reasons. // "REMOTE_IDENT" => "NYI" // env.set("REQUEST_METHOD", req.getMethod()); env.set("SCRIPT_NAME", req.getContextPath() + req.getServletPath()); env.set("SCRIPT_FILENAME", gitwebCgi.toAbsolutePath().toString()); env.set("SERVER_NAME", req.getServerName()); env.set("SERVER_PORT", Integer.toString(req.getServerPort())); env.set("SERVER_PROTOCOL", req.getProtocol()); env.set("SERVER_SOFTWARE", getServletContext().getServerInfo()); final Enumeration<String> hdrs = enumerateHeaderNames(req); while (hdrs.hasMoreElements()) { final String name = hdrs.nextElement(); final String value = req.getHeader(name); env.set("HTTP_" + name.toUpperCase().replace('-', '_'), value); } env.set("GERRIT_CONTEXT_PATH", req.getContextPath() + "/"); env.set("GERRIT_PROJECT_NAME", project.getProject().getName()); if (project.forUser(anonymousUserProvider.get()).isVisible()) { env.set("GERRIT_ANONYMOUS_READ", "1"); } String remoteUser = null; if (project.getCurrentUser().isIdentifiedUser()) { final IdentifiedUser u = (IdentifiedUser) project.getCurrentUser(); final String user = u.getUserName(); env.set("GERRIT_USER_NAME", user); if (user != null && !user.isEmpty()) { remoteUser = user; } else { remoteUser = "******" + u.getAccountId(); } } env.set("REMOTE_USER", remoteUser); // Override CGI settings using alternative URI provided by gitweb.url. // This is required to trick gitweb into thinking that it's served under // different URL. Setting just $my_uri on the perl's side isn't enough, // because few actions (atom, blobdiff_plain, commitdiff_plain) rely on // URL returned by $cgi->self_url(). // if (gitwebUrl != null) { int schemePort = -1; if (gitwebUrl.getScheme() != null) { if (gitwebUrl.getScheme().equals("http")) { env.set("HTTPS", "OFF"); schemePort = 80; } else { env.set("HTTPS", "ON"); schemePort = 443; } } if (gitwebUrl.getHost() != null) { env.set("SERVER_NAME", gitwebUrl.getHost()); env.set("HTTP_HOST", gitwebUrl.getHost()); } if (gitwebUrl.getPort() != -1) { env.set("SERVER_PORT", Integer.toString(gitwebUrl.getPort())); } else if (schemePort != -1) { env.set("SERVER_PORT", Integer.toString(schemePort)); } if (gitwebUrl.getPath() != null) { env.set("SCRIPT_NAME", gitwebUrl.getPath().isEmpty() ? "/" : gitwebUrl.getPath()); } } return env.getEnvArray(); }
/** * Constructs the CGI environment to be supplied to the invoked CGI script; relies heavliy on * Servlet API methods and findCGI * * @param HttpServletRequest request associated with the CGI invokation * @return true if environment was set OK, false if there was a problem and no environment was set */ protected boolean deriveProcessEnvironment(HttpServletRequest req) { /* * This method is slightly ugly; c'est la vie. * "You cannot stop [ugliness], you can only hope to contain [it]" * (apologies to Marv Albert regarding MJ) */ Hashtable envp; super.deriveProcessEnvironment(req); envp = getEnvironment(); String sPathInfoOrig = null; String sPathTranslatedOrig = null; String sPathInfoCGI = null; String sPathTranslatedCGI = null; String sCGIFullPath = null; String sCGIScriptName = null; String sCGIFullName = null; String sCGIName = null; String[] sCGINames; sPathInfoOrig = this.pathInfo; sPathInfoOrig = sPathInfoOrig == null ? "" : sPathInfoOrig; sPathTranslatedOrig = req.getPathTranslated(); sPathTranslatedOrig = sPathTranslatedOrig == null ? "" : sPathTranslatedOrig; sCGINames = findCGI( sPathInfoOrig, getWebAppRootDir(), getContextPath(), getServletPath(), cgiPathPrefix); sCGIFullPath = sCGINames[0]; sCGIScriptName = sCGINames[1]; sCGIFullName = sCGINames[2]; sCGIName = sCGINames[3]; if (sCGIFullPath == null || sCGIScriptName == null || sCGIFullName == null || sCGIName == null) { return false; } envp.put("SERVER_SOFTWARE", "TOMCAT"); envp.put("SERVER_NAME", nullsToBlanks(req.getServerName())); envp.put("GATEWAY_INTERFACE", "CGI/1.1"); envp.put("SERVER_PROTOCOL", nullsToBlanks(req.getProtocol())); int port = req.getServerPort(); Integer iPort = (port == 0 ? new Integer(-1) : new Integer(port)); envp.put("SERVER_PORT", iPort.toString()); envp.put("REQUEST_METHOD", nullsToBlanks(req.getMethod())); /*- * PATH_INFO should be determined by using sCGIFullName: * 1) Let sCGIFullName not end in a "/" (see method findCGI) * 2) Let sCGIFullName equal the pathInfo fragment which * corresponds to the actual cgi script. * 3) Thus, PATH_INFO = request.getPathInfo().substring( * sCGIFullName.length()) * * (see method findCGI, where the real work is done) * */ if (pathInfo == null || (pathInfo.substring(sCGIFullName.length()).length() <= 0)) { sPathInfoCGI = ""; } else { sPathInfoCGI = pathInfo.substring(sCGIFullName.length()); } envp.put("PATH_INFO", sPathInfoCGI); /*- * PATH_TRANSLATED must be determined after PATH_INFO (and the * implied real cgi-script) has been taken into account. * * The following example demonstrates: * * servlet info = /servlet/cgigw/dir1/dir2/cgi1/trans1/trans2 * cgifullpath = /servlet/cgigw/dir1/dir2/cgi1 * path_info = /trans1/trans2 * webAppRootDir = servletContext.getRealPath("/") * * path_translated = servletContext.getRealPath("/trans1/trans2") * * That is, PATH_TRANSLATED = webAppRootDir + sPathInfoCGI * (unless sPathInfoCGI is null or blank, then the CGI * specification dictates that the PATH_TRANSLATED metavariable * SHOULD NOT be defined. * */ if (sPathInfoCGI != null && !("".equals(sPathInfoCGI))) { sPathTranslatedCGI = getContext().getRealPath(sPathInfoCGI); } else { sPathTranslatedCGI = null; } if (sPathTranslatedCGI == null || "".equals(sPathTranslatedCGI)) { // NOOP } else { envp.put("PATH_TRANSLATED", nullsToBlanks(sPathTranslatedCGI)); } envp.put("SCRIPT_NAME", nullsToBlanks(sCGIScriptName)); envp.put("QUERY_STRING", nullsToBlanks(req.getQueryString())); envp.put("REMOTE_HOST", nullsToBlanks(req.getRemoteHost())); envp.put("REMOTE_ADDR", nullsToBlanks(req.getRemoteAddr())); envp.put("AUTH_TYPE", nullsToBlanks(req.getAuthType())); envp.put("REMOTE_USER", nullsToBlanks(req.getRemoteUser())); envp.put("REMOTE_IDENT", ""); // not necessary for full compliance envp.put("CONTENT_TYPE", nullsToBlanks(req.getContentType())); /* Note CGI spec says CONTENT_LENGTH must be NULL ("") or undefined * if there is no content, so we cannot put 0 or -1 in as per the * Servlet API spec. */ int contentLength = req.getContentLength(); String sContentLength = (contentLength <= 0 ? "" : (new Integer(contentLength)).toString()); envp.put("CONTENT_LENGTH", sContentLength); Enumeration headers = req.getHeaderNames(); String header = null; while (headers.hasMoreElements()) { header = null; header = ((String) headers.nextElement()).toUpperCase(); // REMIND: rewrite multiple headers as if received as single // REMIND: change character set // REMIND: I forgot what the previous REMIND means if ("AUTHORIZATION".equalsIgnoreCase(header) || "PROXY_AUTHORIZATION".equalsIgnoreCase(header)) { // NOOP per CGI specification section 11.2 } else if ("HOST".equalsIgnoreCase(header)) { String host = req.getHeader(header); envp.put("HTTP_" + header.replace('-', '_'), host.substring(0, host.indexOf(":"))); } else { envp.put("HTTP_" + header.replace('-', '_'), req.getHeader(header)); } } command = sCGIFullPath; workingDirectory = new File(command.substring(0, command.lastIndexOf(File.separator))); envp.put("X_TOMCAT_COMMAND_PATH", command); // for kicks this.setEnvironment(envp); return true; }
/* * @param root * @param path * @param req * @param res * @exception IOException */ private void exec(File command, String pathInfo, HttpServletRequest req, HttpServletResponse res) throws IOException { String path = command.toString(); File dir = command.getParentFile(); if (log.isDebugEnabled()) log.debug("CGI: execing: " + path); EnvList env = new EnvList(_env); // these ones are from "The WWW Common Gateway Interface Version 1.1" // look at : http://Web.Golux.Com/coar/cgi/draft-coar-cgi-v11-03-clean.html#6.1.1 env.set("AUTH_TYPE", req.getAuthType()); env.set("CONTENT_LENGTH", Integer.toString(req.getContentLength())); env.set("CONTENT_TYPE", req.getContentType()); env.set("GATEWAY_INTERFACE", "CGI/1.1"); env.set("PATH_INFO", pathInfo); env.set("PATH_TRANSLATED", req.getPathTranslated()); env.set("QUERY_STRING", req.getQueryString()); env.set("REMOTE_ADDR", req.getRemoteAddr()); env.set("REMOTE_HOST", req.getRemoteHost()); // The identity information reported about the connection by a // RFC 1413 [11] request to the remote agent, if // available. Servers MAY choose not to support this feature, or // not to request the data for efficiency reasons. // "REMOTE_IDENT" => "NYI" env.set("REMOTE_USER", req.getRemoteUser()); env.set("REQUEST_METHOD", req.getMethod()); String scriptName = req.getRequestURI().substring(0, req.getRequestURI().length() - pathInfo.length()); env.set("SCRIPT_NAME", scriptName); env.set("SCRIPT_FILENAME", getServletContext().getRealPath(scriptName)); env.set("SERVER_NAME", req.getServerName()); env.set("SERVER_PORT", Integer.toString(req.getServerPort())); env.set("SERVER_PROTOCOL", req.getProtocol()); env.set("SERVER_SOFTWARE", getServletContext().getServerInfo()); Enumeration enm = req.getHeaderNames(); while (enm.hasMoreElements()) { String name = (String) enm.nextElement(); String value = req.getHeader(name); env.set("HTTP_" + name.toUpperCase().replace('-', '_'), value); } // these extra ones were from printenv on www.dev.nomura.co.uk env.set("HTTPS", (req.isSecure() ? "ON" : "OFF")); // "DOCUMENT_ROOT" => root + "/docs", // "SERVER_URL" => "NYI - http://us0245", // "TZ" => System.getProperty("user.timezone"), // are we meant to decode args here ? or does the script get them // via PATH_INFO ? if we are, they should be decoded and passed // into exec here... String execCmd = path; if (execCmd.indexOf(" ") >= 0) execCmd = "\"" + execCmd + "\""; if (_cmdPrefix != null) execCmd = _cmdPrefix + " " + execCmd; Process p = dir == null ? Runtime.getRuntime().exec(execCmd, env.getEnvArray()) : Runtime.getRuntime().exec(execCmd, env.getEnvArray(), dir); // hook processes input to browser's output (async) final InputStream inFromReq = req.getInputStream(); final OutputStream outToCgi = p.getOutputStream(); final int inputLength = req.getContentLength(); new Thread( new Runnable() { public void run() { try { if (inputLength > 0) IO.copy(inFromReq, outToCgi, inputLength); outToCgi.close(); } catch (IOException e) { LogSupport.ignore(log, e); } } }) .start(); // hook processes output to browser's input (sync) // if browser closes stream, we should detect it and kill process... try { // read any headers off the top of our input stream LineInput li = new LineInput(p.getInputStream()); HttpFields fields = new HttpFields(); fields.read(li); String ContentStatus = "Status"; String redirect = fields.get(HttpFields.__Location); String status = fields.get(ContentStatus); if (status != null) { log.debug("Found a Status header - setting status on response"); fields.remove(ContentStatus); // NOTE: we ignore any reason phrase, otherwise we // would need to use res.sendError() selectively. int i = status.indexOf(' '); if (i > 0) status = status.substring(0, i); res.setStatus(Integer.parseInt(status)); } // copy remaining headers into response... for (Iterator i = fields.iterator(); i.hasNext(); ) { HttpFields.Entry e = (HttpFields.Entry) i.next(); res.addHeader(e.getKey(), e.getValue()); } if (status == null && redirect != null) { // The CGI has set Location and is counting on us to do the redirect. // See http://CGI-Spec.Golux.Com/draft-coar-cgi-v11-03-clean.html#7.2.1.2 if (!redirect.startsWith("http:/") && !redirect.startsWith("https:/")) res.sendRedirect(redirect); else res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); } // copy remains of input onto output... IO.copy(li, res.getOutputStream()); p.waitFor(); int exitValue = p.exitValue(); if (log.isDebugEnabled()) log.debug("CGI: p.exitValue(): " + exitValue); if (0 != exitValue) { log.warn("Non-zero exit status (" + exitValue + ") from CGI program: " + path); if (!res.isCommitted()) res.sendError(500, "Failed to exec CGI"); } } catch (IOException e) { // browser has probably closed its input stream - we // terminate and clean up... log.debug("CGI: Client closed connection!"); } catch (InterruptedException ie) { log.debug("CGI: interrupted!"); } finally { p.destroy(); } if (log.isDebugEnabled()) log.debug("CGI: Finished exec: " + p); }
public TaskHttpServletRequest(HttpServletRequest wrapping, Task task) { this.session = wrapping.getSession(); String location = wrapping.getParameter("url"); cookies = wrapping.getCookies(); characterEncoding = wrapping.getCharacterEncoding(); authType = wrapping.getAuthType(); headerNames = new Vector<String>(); headers = new MultiMap(); for (Enumeration e = wrapping.getHeaderNames(); e.hasMoreElements(); ) { String headerName = (String) e.nextElement(); for (Enumeration f = wrapping.getHeaders(headerName); f.hasMoreElements(); ) { String headerValue = (String) f.nextElement(); headers.add(headerName, headerValue); } } contextPath = wrapping.getContextPath(); pathInfo = wrapping.getPathInfo(); pathTranslated = wrapping.getPathTranslated(); remoteUser = wrapping.getRemoteUser(); // TODO check if needed requestedSessionId = wrapping.getRequestedSessionId(); // TODO check if needed userPrincipal = wrapping.getUserPrincipal(); // TODO check if needed requestedSessionIdFromCookie = wrapping.isRequestedSessionIdFromCookie(); requestedSessionIdFromURL = wrapping.isRequestedSessionIdFromURL(); requestedSessionIdValid = wrapping.isRequestedSessionIdValid(); localAddr = wrapping.getLocalAddr(); localName = wrapping.getLocalName(); localPort = wrapping.getLocalPort(); locale = wrapping.getLocale(); locales = new Vector<Locale>(); for (Enumeration e = wrapping.getLocales(); e.hasMoreElements(); locales.add((Locale) e.nextElement())) ; protocol = wrapping.getProtocol(); remoteAddr = wrapping.getRemoteAddr(); remoteHost = wrapping.getRemoteHost(); remotePort = wrapping.getRemotePort(); scheme = wrapping.getScheme(); serverName = wrapping.getServerName(); serverPort = wrapping.getServerPort(); secure = wrapping.isSecure(); // Extract the query (everything after ?) int idx = location.indexOf('?'); query = null; if (idx != -1) { query = location.substring(idx + 1); } // Extract the URI (everything before ?) uri = location; if (idx != -1) { uri = uri.substring(0, idx); } // Servlet path (same as URI?) servletPath = uri; // Extract parameters params = new Hashtable<String, String[]>(); if (query != null) { StringTokenizer t = new StringTokenizer(query, "&"); while (t.hasMoreTokens()) { String token = t.nextToken(); idx = token.indexOf('='); String name = token; String val = null; if (idx != -1) { name = token.substring(0, idx); val = token.substring(idx + 1); } else { val = ""; } String[] vals = params.get(name); if (vals == null) { vals = new String[] {val}; } else { String[] nvals = new String[vals.length + 1]; System.arraycopy(vals, 0, nvals, 0, vals.length); nvals[vals.length] = val; vals = nvals; } params.put(name, vals); } } // Initialise attributes attributes = new Hashtable<String, Object>(); // Create the URL (the URL with protocol / host / post) try { URL u = new URL(new URL(wrapping.getRequestURL().toString()), uri); url = new StringBuffer(u.toExternalForm()); } catch (MalformedURLException e) { } setAttribute(ATTR_TASK, task); }
@Override public void onTrigger(final ProcessContext context, final ProcessSession session) throws ProcessException { try { if (!initialized.get()) { initializeServer(context); } } catch (Exception e) { context.yield(); throw new ProcessException("Failed to initialize the server", e); } final HttpRequestContainer container = containerQueue.poll(); if (container == null) { return; } final long start = System.nanoTime(); final HttpServletRequest request = container.getRequest(); FlowFile flowFile = session.create(); try { flowFile = session.importFrom(request.getInputStream(), flowFile); } catch (final IOException e) { getLogger() .error( "Failed to receive content from HTTP Request from {} due to {}", new Object[] {request.getRemoteAddr(), e}); session.remove(flowFile); return; } final String charset = request.getCharacterEncoding() == null ? context.getProperty(URL_CHARACTER_SET).getValue() : request.getCharacterEncoding(); final String contextIdentifier = UUID.randomUUID().toString(); final Map<String, String> attributes = new HashMap<>(); try { putAttribute(attributes, HTTPUtils.HTTP_CONTEXT_ID, contextIdentifier); putAttribute(attributes, "mime.type", request.getContentType()); putAttribute(attributes, "http.servlet.path", request.getServletPath()); putAttribute(attributes, "http.context.path", request.getContextPath()); putAttribute(attributes, "http.method", request.getMethod()); putAttribute(attributes, "http.local.addr", request.getLocalAddr()); putAttribute(attributes, HTTPUtils.HTTP_LOCAL_NAME, request.getLocalName()); if (request.getQueryString() != null) { putAttribute( attributes, "http.query.string", URLDecoder.decode(request.getQueryString(), charset)); } putAttribute(attributes, HTTPUtils.HTTP_REMOTE_HOST, request.getRemoteHost()); putAttribute(attributes, "http.remote.addr", request.getRemoteAddr()); putAttribute(attributes, "http.remote.user", request.getRemoteUser()); putAttribute(attributes, HTTPUtils.HTTP_REQUEST_URI, request.getRequestURI()); putAttribute(attributes, "http.request.url", request.getRequestURL().toString()); putAttribute(attributes, "http.auth.type", request.getAuthType()); putAttribute(attributes, "http.requested.session.id", request.getRequestedSessionId()); if (request.getDispatcherType() != null) { putAttribute(attributes, "http.dispatcher.type", request.getDispatcherType().name()); } putAttribute(attributes, "http.character.encoding", request.getCharacterEncoding()); putAttribute(attributes, "http.locale", request.getLocale()); putAttribute(attributes, "http.server.name", request.getServerName()); putAttribute(attributes, HTTPUtils.HTTP_PORT, request.getServerPort()); final Enumeration<String> paramEnumeration = request.getParameterNames(); while (paramEnumeration.hasMoreElements()) { final String paramName = paramEnumeration.nextElement(); final String value = request.getParameter(paramName); attributes.put("http.param." + paramName, value); } final Cookie[] cookies = request.getCookies(); if (cookies != null) { for (final Cookie cookie : cookies) { final String name = cookie.getName(); final String cookiePrefix = "http.cookie." + name + "."; attributes.put(cookiePrefix + "value", cookie.getValue()); attributes.put(cookiePrefix + "domain", cookie.getDomain()); attributes.put(cookiePrefix + "path", cookie.getPath()); attributes.put(cookiePrefix + "max.age", String.valueOf(cookie.getMaxAge())); attributes.put(cookiePrefix + "version", String.valueOf(cookie.getVersion())); attributes.put(cookiePrefix + "secure", String.valueOf(cookie.getSecure())); } } final String queryString = request.getQueryString(); if (queryString != null) { final String[] params = URL_QUERY_PARAM_DELIMITER.split(queryString); for (final String keyValueString : params) { final int indexOf = keyValueString.indexOf("="); if (indexOf < 0) { // no =, then it's just a key with no value attributes.put("http.query.param." + URLDecoder.decode(keyValueString, charset), ""); } else { final String key = keyValueString.substring(0, indexOf); final String value; if (indexOf == keyValueString.length() - 1) { value = ""; } else { value = keyValueString.substring(indexOf + 1); } attributes.put( "http.query.param." + URLDecoder.decode(key, charset), URLDecoder.decode(value, charset)); } } } } catch (final UnsupportedEncodingException uee) { throw new ProcessException( "Invalid character encoding", uee); // won't happen because charset has been validated } final Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { final String headerName = headerNames.nextElement(); final String headerValue = request.getHeader(headerName); putAttribute(attributes, "http.headers." + headerName, headerValue); } final Principal principal = request.getUserPrincipal(); if (principal != null) { putAttribute(attributes, "http.principal.name", principal.getName()); } final X509Certificate certs[] = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate"); final String subjectDn; if (certs != null && certs.length > 0) { final X509Certificate cert = certs[0]; subjectDn = cert.getSubjectDN().getName(); final String issuerDn = cert.getIssuerDN().getName(); putAttribute(attributes, HTTPUtils.HTTP_SSL_CERT, subjectDn); putAttribute(attributes, "http.issuer.dn", issuerDn); } else { subjectDn = null; } flowFile = session.putAllAttributes(flowFile, attributes); final HttpContextMap contextMap = context.getProperty(HTTP_CONTEXT_MAP).asControllerService(HttpContextMap.class); final boolean registered = contextMap.register( contextIdentifier, request, container.getResponse(), container.getContext()); if (!registered) { getLogger() .warn( "Received request from {} but could not process it because too many requests are already outstanding; responding with SERVICE_UNAVAILABLE", new Object[] {request.getRemoteAddr()}); try { container.getResponse().setStatus(Status.SERVICE_UNAVAILABLE.getStatusCode()); container.getResponse().flushBuffer(); container.getContext().complete(); } catch (final Exception e) { getLogger() .warn( "Failed to respond with SERVICE_UNAVAILABLE message to {} due to {}", new Object[] {request.getRemoteAddr(), e}); } session.remove(flowFile); return; } final long receiveMillis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start); session .getProvenanceReporter() .receive( flowFile, HTTPUtils.getURI(attributes), "Received from " + request.getRemoteAddr() + (subjectDn == null ? "" : " with DN=" + subjectDn), receiveMillis); session.transfer(flowFile, REL_SUCCESS); getLogger() .info( "Transferring {} to 'success'; received from {}", new Object[] {flowFile, request.getRemoteAddr()}); }