Mercurial Hosting > nabble
view src/nabble/view/web/template/NamlServlet.java @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children |
line wrap: on
line source
package nabble.view.web.template; import fschmidt.util.servlet.AuthorizingServlet; import fschmidt.util.servlet.CanonicalUrl; import fschmidt.util.servlet.JtpContext; import fschmidt.util.servlet.ServletUtils; import nabble.model.Site; import nabble.model.User; import nabble.modules.ModuleManager; import nabble.naml.compiler.Command; import nabble.naml.compiler.CompileException; import nabble.naml.compiler.IPrintWriter; import nabble.naml.compiler.Interpreter; import nabble.naml.compiler.Namespace; import nabble.naml.compiler.Template; import nabble.naml.compiler.TemplateRuntimeException; import nabble.naml.namespaces.BasicNamespace; import nabble.view.lib.Jtp; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Date; public final class NamlServlet extends HttpServlet implements CanonicalUrl, AuthorizingServlet { private static String runTemplate(HttpServletRequest request,String templateName) throws ServletException { Site site = Jtp.getSite(request); if( site == null ) return null; Template template = site.getTemplate( templateName , BasicNamespace.class, NabbleNamespace.class, RequestNamespace.class ); if( template == null ) return null; StringWriter sw = new StringWriter(); try { ModuleManager.run( template, sw, Collections.<String,Object>emptyMap(), new BasicNamespace(template), new NabbleNamespace(site), new RequestNamespace(request) ); } catch(IOException e) { throw new RuntimeException(e); } catch(TemplateRuntimeException e) { checkTweaked(request,site,e); throw e; } return sw.toString(); } public String getCanonicalUrl(HttpServletRequest request) { if( request.getParameterMap().isEmpty() ) return Jtp.homePage(); try { String macroName = request.getParameter("macro"); String path = runTemplate(request,macroName+" canonical path"); if( path == null ) return null; path = path.trim(); if( path.length() > 0 ) return Jtp.getBaseUrl(request)+path; } catch(ServletException e) { return null; } /* why bother? - fschmidt Site site = Jtp.getSite(request); StringBuilder url = new StringBuilder(); url.append( site.getBaseUrl() ).append( request.getServletPath() ); String pathInfo = request.getPathInfo(); if( pathInfo != null ) url.append( pathInfo ); String query = request.getQueryString(); if( query != null ) url.append( '?' ).append( query ); return url.toString(); */ return null; } public String getAuthorizationKey(HttpServletRequest request) throws ServletException { String s = runTemplate(request,"get read authorization key"); if( s == null ) return null; s = s.trim(); return s.length() > 0 ? s : null; } @Namespace ( name = "read_authorization", global = true ) public static final class ReadAuthorization { private final String key; private ReadAuthorization(String key) { this.key = key; } @Command public void authorization_key(IPrintWriter out,Interpreter interp) { out.print(key); } } public boolean authorize(String key,HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { Site site = Jtp.getSiteNotNull(request); Template template = site.getTemplate( "authorize for read" , BasicNamespace.class, NabbleNamespace.class, ServletNamespace.class, ReadAuthorization.class ); StringWriter sw = new StringWriter(); ModuleManager.run( template, sw, Collections.<String,Object>emptyMap(), new BasicNamespace(template), new NabbleNamespace(site), new ServletNamespace(request,response), new ReadAuthorization(key) ); String s = sw.toString(); return s.trim().equals("true"); } protected void service(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { Site site = Jtp.getSite(request); if( site == null ) { response.sendError(HttpServletResponse.SC_NOT_FOUND, "Site Not Found"); return; } try { service(site,request,response); } catch(TemplateRuntimeException e) { Throwable cause = e.getCause(); if( cause instanceof CompileException ) { CompileException ce = (CompileException)cause; if( site.setTweakException(ce) ) { service(site,request,response); return; } } checkTweaked(request,site,e); throw e; } } private void service(Site site,HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { String macroName = request.getParameter("macro"); if( macroName == null ) throw Jtp.servletException(request,"macroName is null"); Template template = site.getTemplate(macroName, BasicNamespace.class, NabbleNamespace.class, ServletNamespace.class ); if( template == null ) throw Jtp.servletException(request,"macro not found: "+macroName); response.setHeader("X-XSS-Protection","0"); BasicNamespace basicNs = new BasicNamespace(template); NabbleNamespace nabbleNs = new NabbleNamespace(site); ServletNamespace servletNs = new ServletNamespace(request, response); StringWriter sw = new StringWriter(); PrintWriter out = new PrintWriter(sw); ModuleManager.run( template, out, Collections.<String,Object>emptyMap(), basicNs, nabbleNs, servletNs ); out.flush(); if( servletNs.cacheEvents != null ) { JtpContext jtpContext = (JtpContext)getServletContext().getAttribute(JtpContext.attrName); jtpContext.setEtag(request,response, servletNs.cacheEvents.toArray(new String[servletNs.cacheEvents.size()]) ); } response.getWriter().print(sw.toString()); } private static void checkTweaked(HttpServletRequest request,Site site,TemplateRuntimeException e) throws ServletException { if( !site.getCustomTweaks().isEmpty() ) { NamlLogger logger = NamlLogger.getLogger(site); DateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); logger.log( dateFmt.format(new Date()) + " " + ServletUtils.getCurrentURL(request) + " referer=" + request.getHeader("referer")); logger.log("IP = "+Jtp.getClientIpAddr(request)); User user = Jtp.getUser(request); if( user != null ) logger.log("user = "+user.getId()); logger.log(e.toString()); logger.log(""); throw new ServletException("NAML exception in customized site: "+e.getMessage(),e); } } }