public void init() throws javax.servlet.ServletException { super.init(); org.slf4j.Logger logServerStartup = org.slf4j.LoggerFactory.getLogger("serverStartup"); logServerStartup.info( getClass().getName() + " initialization start - " + UsageLog.setupNonRequestContext()); this.ascLimit = ThreddsConfig.getInt("Opendap.ascLimit", ascLimit); this.binLimit = ThreddsConfig.getInt("Opendap.binLimit", binLimit); this.odapVersionString = ThreddsConfig.get("Opendap.serverVersion", odapVersionString); logServerStartup.info( getClass().getName() + " version= " + odapVersionString + " ascLimit = " + ascLimit + " binLimit = " + binLimit); // debugging actions makeDebugActions(); logServerStartup.info( getClass().getName() + " initialization done - " + UsageLog.closingMessageNonRequestContext()); }
// any time the server needs access to the dataset, it gets a "GuardedDataset" which allows us to // add caching // optionally, a session may be established, which allows us to reserve the dataset for that // session. protected GuardedDataset getDataset(ReqState preq) throws Exception { HttpServletRequest req = preq.getRequest(); String reqPath = preq.getDataSet(); // see if the client wants sessions boolean acceptSession = false; String s = req.getHeader("X-Accept-Session"); if (s != null && s.equalsIgnoreCase("true") && allowSessions) acceptSession = true; HttpSession session = null; if (acceptSession) { // see if theres already a session established, create one if not session = req.getSession(); if (!session.isNew()) { GuardedDataset gdataset = (GuardedDataset) session.getAttribute(reqPath); if (null != gdataset) { if (debugSession) System.out.printf(" found gdataset %s in session %s %n", reqPath, session.getId()); if (log.isDebugEnabled()) log.debug(" found gdataset " + gdataset + " in session " + session.getId()); return gdataset; } } } NetcdfFile ncd = DatasetHandler.getNetcdfFile(req, preq.getResponse(), reqPath); if (null == ncd) return null; GuardedDataset gdataset = new GuardedDatasetCacheAndClone(reqPath, ncd, acceptSession); // GuardedDataset gdataset = new GuardedDatasetImpl(reqPath, ncd, acceptSession); if (acceptSession) { String cookiePath = req.getRequestURI(); String suffix = "." + preq.getRequestSuffix(); if (cookiePath.endsWith(suffix)) // snip off the suffix cookiePath = cookiePath.substring(0, cookiePath.length() - suffix.length()); session.setAttribute(reqPath, gdataset); session.setAttribute(CookieFilter.SESSION_PATH, cookiePath); // session.setAttribute("dataset", ncd.getLocation()); // for UsageValve // session.setMaxInactiveInterval(30); // 30 second timeout !! if (debugSession) System.out.printf( " added gdataset %s in session %s cookiePath %s %n", reqPath, session.getId(), cookiePath); if (log.isDebugEnabled()) log.debug(" added gdataset " + gdataset + " in session " + session.getId()); } /* else { session = req.getSession(); session.setAttribute("dataset", ncd.getLocation()); // for UsageValve } */ return gdataset; }
private void checkSize(ServerDDS dds, boolean isAscii) throws Exception { long size = computeSize(dds, isAscii); // System.err.printf("total (constrained) size=%s\n", size); log.debug("total (constrained) size={}", size); double dsize = size / (1000 * 1000); double maxSize = isAscii ? ascLimit : binLimit; // Mbytes if (dsize > maxSize) { log.info("Reject request size = {} Mbytes", dsize); throw new UnsupportedOperationException( "Request too big=" + dsize + " Mbytes, max=" + maxSize); } }
private void sendErrorResponse(HttpServletResponse response, int errorCode, String errorMessage) { try { log.info(UsageLog.closingMessageForRequestContext(errorCode, -1)); response.setStatus(errorCode); response.setHeader("Content-Description", "dods-error"); response.setContentType("text/plain"); PrintWriter pw = new PrintWriter(response.getOutputStream()); pw.println("Error {"); pw.println(" code = " + errorCode + ";"); pw.println(" message = \"" + errorMessage + "\";"); pw.println("};"); pw.flush(); } catch (Exception e) { System.err.println("sendErrorResponse: " + e); } }
/** * @param request * @param response * @return the request state */ protected ReqState getRequestState(HttpServletRequest request, HttpServletResponse response) { ReqState rs = null; // Assume url was encoded String baseurl = request.getRequestURL().toString(); baseurl = EscapeStrings.unescapeURL(baseurl); // Assume query was encoded String query = request.getQueryString(); query = EscapeStrings.unescapeURLQuery(query); log.info(String.format("OpendapServlet: nominal url: %s?%s", baseurl, query)); try { rs = new ReqState(request, response, this, getServerName(), baseurl, query); } catch (Exception bue) { rs = null; } return rs; }
public void doGetASC(ReqState rs) throws Exception { HttpServletResponse response = rs.getResponse(); GuardedDataset ds = null; try { ds = getDataset(rs); if (ds == null) return; response.setHeader("XDODS-Server", getServerVersion()); response.setContentType("text/plain"); response.setHeader("Content-Description", "dods-ascii"); log.debug( "Sending OPeNDAP ASCII Data For: " + rs + " CE: '" + rs.getConstraintExpression() + "'"); ServerDDS dds = ds.getDDS(); CEEvaluator ce = new CEEvaluator(dds); ce.parseConstraint(rs); checkSize(dds, true); PrintWriter pw = new PrintWriter(response.getOutputStream()); dds.printConstrained(pw); pw.println("---------------------------------------------"); AsciiWriter writer = new AsciiWriter(); // could be static writer.toASCII(pw, dds, ds); // the way that getDAP2Data works // DataOutputStream sink = new DataOutputStream(bOut); // ce.send(myDDS.getName(), sink, ds); pw.flush(); } finally { // release lock if needed if (ds != null) ds.release(); } }
public void doGet(HttpServletRequest request, HttpServletResponse response) { log.info("doGet(): " + UsageLog.setupRequestContext(request)); // System.out.printf("opendap doGet: req=%s%n%s%n", ServletUtil.getRequest(request), // ServletUtil.showRequestDetail(this, request)); String path = null; ReqState rs = getRequestState(request, response); try { path = request.getPathInfo(); log.debug("doGet path={}", path); if (thredds.servlet.Debug.isSet("showRequestDetail")) log.debug(ServletUtil.showRequestDetail(this, request)); if (path == null) { log.info( "doGet(): " + UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_NOT_FOUND, -1)); response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } if (baseURI == null) { // first time, set baseURI URI reqURI = ServletUtil.getRequestURI(request); // Build base URI from request (rather than hard-coding "/thredds/dodsC/"). String baseUriString = request.getContextPath() + request.getServletPath() + "/"; baseURI = reqURI.resolve(baseUriString); log.debug("doGet(): baseURI was set = {}", baseURI); } if (path.endsWith("latest.xml")) { DataRootHandler.getInstance().processReqForLatestDataset(this, request, response); return; } // Redirect all catalog requests at the root level. if (path.equals("/") || path.equals("/catalog.html") || path.equals("/catalog.xml")) { ServletUtil.sendPermanentRedirect(ServletUtil.getContextPath() + path, request, response); return; } // Make sure catalog requests match a dataRoot before trying to handle. if (path.endsWith("/") || path.endsWith("/catalog.html") || path.endsWith("/catalog.xml")) { if (!DataRootHandler.getInstance().hasDataRootMatch(path)) { log.info( "doGet(): " + UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_NOT_FOUND, -1)); response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } if (!DataRootHandler.getInstance().processReqForCatalog(request, response)) log.error( "doGet(): " + UsageLog.closingMessageForRequestContext( ServletUtil.STATUS_FORWARD_FAILURE, -1)); return; } if (rs != null) { String dataSet = rs.getDataSet(); String requestSuffix = rs.getRequestSuffix(); if ((dataSet == null) || dataSet.equals("/") || dataSet.equals("")) { doGetDIR(rs); } else if (requestSuffix.equalsIgnoreCase("blob")) { doGetBLOB(rs); } else if (requestSuffix.equalsIgnoreCase("close")) { doClose(rs); } else if (requestSuffix.equalsIgnoreCase("dds")) { doGetDDS(rs); } else if (requestSuffix.equalsIgnoreCase("das")) { doGetDAS(rs); } else if (requestSuffix.equalsIgnoreCase("ddx")) { doGetDDX(rs); } else if (requestSuffix.equalsIgnoreCase("dods")) { doGetDAP2Data(rs); } else if (requestSuffix.equalsIgnoreCase("asc") || requestSuffix.equalsIgnoreCase("ascii")) { doGetASC(rs); } else if (requestSuffix.equalsIgnoreCase("info")) { doGetINFO(rs); } else if (requestSuffix.equalsIgnoreCase("html") || requestSuffix.equalsIgnoreCase("htm")) { doGetHTML(rs); } else if (requestSuffix.equalsIgnoreCase("ver") || requestSuffix.equalsIgnoreCase("version") || dataSet.equalsIgnoreCase("/version") || dataSet.equalsIgnoreCase("/version/")) { doGetVER(rs); } else if (dataSet.equalsIgnoreCase("/help") || dataSet.equalsIgnoreCase("/help/") || dataSet.equalsIgnoreCase("/" + requestSuffix) || requestSuffix.equalsIgnoreCase("help")) { doGetHELP(rs); } else { sendErrorResponse(response, HttpServletResponse.SC_BAD_REQUEST, "Unrecognized request"); return; } } else { sendErrorResponse(response, HttpServletResponse.SC_BAD_REQUEST, "Unrecognized request"); return; } log.info(UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_OK, -1)); // plain ol' 404 } catch (FileNotFoundException e) { sendErrorResponse(response, HttpServletResponse.SC_NOT_FOUND, e.getMessage()); // DAP2Exception bad url } catch (BadURLException e) { log.info(UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_BAD_REQUEST, -1)); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); dap2ExceptionHandler(e, rs); // all other DAP2Exception } catch (DAP2Exception de) { int status = (de.getErrorCode() == DAP2Exception.NO_SUCH_FILE) ? HttpServletResponse.SC_NOT_FOUND : HttpServletResponse.SC_BAD_REQUEST; if ((de.getErrorCode() != DAP2Exception.NO_SUCH_FILE) && (de.getErrorMessage() != null)) log.debug(de.getErrorMessage()); log.info(UsageLog.closingMessageForRequestContext(status, -1)); response.setStatus(status); dap2ExceptionHandler(de, rs); // parsing, usually the CE } catch (ParseException pe) { log.info(UsageLog.closingMessageForRequestContext(HttpServletResponse.SC_BAD_REQUEST, -1)); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); parseExceptionHandler(pe, response); // 403 - request too big } catch (UnsupportedOperationException e) { sendErrorResponse(response, HttpServletResponse.SC_FORBIDDEN, e.getMessage()); } catch (java.net.SocketException e) { log.info("SocketException: " + e.getMessage(), e); log.info(UsageLog.closingMessageForRequestContext(ServletUtil.STATUS_CLIENT_ABORT, -1)); } catch (IOException e) { String eName = e.getClass().getName(); // dont want compile time dependency on ClientAbortException if (eName.equals("org.apache.catalina.connector.ClientAbortException")) { log.debug("ClientAbortException: " + e.getMessage()); log.info(UsageLog.closingMessageForRequestContext(ServletUtil.STATUS_CLIENT_ABORT, -1)); return; } log.error("path= " + path, e); sendErrorResponse(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); // everything else } catch (Throwable t) { log.error("path= " + path, t); t.printStackTrace(); sendErrorResponse(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, t.getMessage()); } }