Search in sources :

Example 1 with Descriptor

use of org.exist.http.Descriptor in project exist by eXist-db.

the class XQueryServlet method process.

/**
 * Processes incoming HTTP requests for XQuery.
 *
 * @param request the http request
 * @param response the http response
 *
 * @throws ServletException if the servlet raises an exception
 * @throws IOException if an I/O error occurs
 */
protected void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // first, adjust the path
    String path = request.getPathTranslated();
    if (path == null) {
        path = request.getRequestURI().substring(request.getContextPath().length());
        final int p = path.lastIndexOf(';');
        if (p != Constants.STRING_NOT_FOUND) {
            path = path.substring(0, p);
        }
        path = getServletContext().getRealPath(path);
    }
    // second, perform descriptor actions
    final Descriptor descriptor = Descriptor.getDescriptorSingleton();
    if (descriptor != null && !descriptor.requestsFiltered()) {
        // logs the request if specified in the descriptor
        descriptor.doLogRequestInReplayLog(request);
        // map's the path if a mapping is specified in the descriptor
        path = descriptor.mapPath(path);
    }
    // if (request.getCharacterEncoding() == null)
    // try {
    // request.setCharacterEncoding(formEncoding);
    // } catch (IllegalStateException e) {
    // }
    final ServletOutputStream sout = response.getOutputStream();
    final PrintWriter output = new PrintWriter(new OutputStreamWriter(sout, getFormEncoding()));
    // response.setContentType(contentType + "; charset=" + formEncoding);
    response.addHeader("pragma", "no-cache");
    response.addHeader("Cache-Control", "no-cache");
    String requestPath = request.getRequestURI();
    final int p = requestPath.lastIndexOf('/');
    if (p != Constants.STRING_NOT_FOUND) {
        requestPath = requestPath.substring(0, p);
    }
    String moduleLoadPath;
    final Object loadPathAttrib = request.getAttribute(ATTR_MODULE_LOAD_PATH);
    if (loadPathAttrib != null) {
        moduleLoadPath = getValue(loadPathAttrib);
    } else {
        moduleLoadPath = getServletContext().getRealPath(requestPath.substring(request.getContextPath().length()));
    }
    Subject user = getDefaultUser();
    // to determine the user, first check the request attribute "xquery.user", then
    // the current session attribute "user"
    final Object userAttrib = request.getAttribute(ATTR_XQUERY_USER);
    final HttpSession session = request.getSession(false);
    if (userAttrib != null || (session != null && request.isRequestedSessionIdValid())) {
        final Object passwdAttrib = request.getAttribute(ATTR_XQUERY_PASSWORD);
        String username;
        String password;
        if (userAttrib != null) {
            username = getValue(userAttrib);
            password = getValue(passwdAttrib);
        } else {
            username = getSessionAttribute(session, "user");
            password = getSessionAttribute(session, "password");
        }
        // TODO authentication should use super.authenticate(...) !!!
        try {
            if (username != null && password != null) {
                Subject newUser = getPool().getSecurityManager().authenticate(username, password);
                if (newUser != null && newUser.isAuthenticated()) {
                    user = newUser;
                }
            }
        } catch (final AuthenticationException e) {
            getLog().error("User can not be authenticated ({}).", username);
        }
    }
    if (user == getDefaultUser()) {
        Subject requestUser = HttpAccount.getUserFromServletRequest(request);
        if (requestUser != null) {
            user = requestUser;
        } else {
            requestUser = getAuthenticator().authenticate(request, response, false);
            if (requestUser != null) {
                user = requestUser;
            }
        }
    }
    Source source = null;
    final Object sourceAttrib = request.getAttribute(ATTR_XQUERY_SOURCE);
    final Object urlAttrib = request.getAttribute(ATTR_XQUERY_URL);
    if (sourceAttrib != null) {
        String s;
        if (sourceAttrib instanceof Item)
            try {
                s = ((Item) sourceAttrib).getStringValue();
            } catch (final XPathException e) {
                throw new ServletException("Failed to read XQuery source string from " + "request attribute '" + ATTR_XQUERY_SOURCE + "': " + e.getMessage(), e);
            }
        else {
            s = sourceAttrib.toString();
        }
        source = new StringSource(s);
    } else if (urlAttrib != null) {
        try (final DBBroker broker = getPool().get(Optional.ofNullable(user))) {
            source = SourceFactory.getSource(broker, moduleLoadPath, urlAttrib.toString(), true);
            if (source == null) {
                final String msg = "Could not read source: context=" + moduleLoadPath + ", location=" + urlAttrib.toString();
                getLog().error(msg);
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                sendError(output, "Error", msg);
            }
        } catch (final Exception e) {
            getLog().error(e.getMessage(), e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            sendError(output, "Error", e.getMessage());
        }
    } else {
        final Path f = Paths.get(path);
        if (!Files.isReadable(f)) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            sendError(output, "Cannot read source file", path);
            return;
        }
        source = new FileSource(f, Charset.forName(encoding), true);
    }
    if (source == null) {
        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        sendError(output, "Source not found", path);
    }
    boolean reportErrors = false;
    final String errorOpt = (String) request.getAttribute(ATTR_XQUERY_REPORT_ERRORS);
    if (errorOpt != null) {
        reportErrors = errorOpt.equalsIgnoreCase("YES");
    }
    // allow source viewing for GET?
    if ("GET".equals(request.getMethod().toUpperCase())) {
        String option;
        boolean allowSource = false;
        if ((option = request.getParameter("_source")) != null)
            allowSource = "yes".equals(option);
        // Should we display the source of the XQuery or execute it
        if (allowSource && descriptor != null) {
            // System.out.println("path="+path);
            if (descriptor.allowSource(path)) {
                if (source instanceof DBSource) {
                    try {
                        ((DBSource) source).validate(user, Permission.READ);
                    } catch (final PermissionDeniedException e) {
                        if (getDefaultUser().equals(user)) {
                            getAuthenticator().sendChallenge(request, response);
                        } else {
                            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Permission to view XQuery source for: " + path + " denied. (no read access)");
                        }
                        return;
                    }
                }
                // Show the source of the XQuery
                // writeResourceAs(resource, broker, stylesheet, encoding, "text/plain", outputProperties, response);
                response.setContentType("text/plain; charset=" + getFormEncoding());
                output.write(source.getContent());
                output.flush();
                return;
            } else {
                response.sendError(HttpServletResponse.SC_FORBIDDEN, "Permission to view XQuery source for: " + path + " denied. Must be explicitly defined in descriptor.xml");
                return;
            }
        }
    }
    // -------------------------------
    // URI baseUri;
    // try {
    // baseUri = new URI(request.getScheme(),
    // null/*user info?*/, request.getLocalPart(), request.getLocalPort(),
    // request.getRequestURI(), null, null);
    // } catch(URISyntaxException e) {
    // baseUri = null;
    // }
    final String requestAttr = (String) request.getAttribute(ATTR_XQUERY_ATTRIBUTE);
    try (final DBBroker broker = getPool().get(Optional.ofNullable(user))) {
        final XQuery xquery = broker.getBrokerPool().getXQueryService();
        CompiledXQuery query = getPool().getXQueryPool().borrowCompiledXQuery(broker, source);
        XQueryContext context;
        if (query == null) {
            context = new XQueryContext(getPool());
            context.setModuleLoadPath(moduleLoadPath);
            try {
                query = xquery.compile(context, source);
            } catch (final XPathException ex) {
                throw new EXistException("Cannot compile xquery: " + ex.getMessage(), ex);
            } catch (final IOException ex) {
                throw new EXistException("I/O exception while compiling xquery: " + ex.getMessage(), ex);
            }
        } else {
            context = query.getContext();
            context.setModuleLoadPath(moduleLoadPath);
            context.prepareForReuse();
        }
        final Properties outputProperties = new Properties();
        outputProperties.put("base-uri", collectionURI.toString());
        final HttpRequestWrapper reqw = new HttpRequestWrapper(request, getFormEncoding(), getContainerEncoding());
        final ResponseWrapper respw = new HttpResponseWrapper(response);
        context.setHttpContext(new XQueryContext.HttpContext(reqw, respw, session != null ? new HttpSessionWrapper(session) : null));
        final String timeoutOpt = (String) request.getAttribute(ATTR_TIMEOUT);
        if (timeoutOpt != null) {
            try {
                final long timeout = Long.parseLong(timeoutOpt);
                context.getWatchDog().setTimeout(timeout);
            } catch (final NumberFormatException e) {
                throw new EXistException("Bad timeout option: " + timeoutOpt);
            }
        }
        final String maxNodesOpt = (String) request.getAttribute(ATTR_MAX_NODES);
        if (maxNodesOpt != null) {
            try {
                final int maxNodes = Integer.parseInt(maxNodesOpt);
                context.getWatchDog().setMaxNodes(maxNodes);
            } catch (final NumberFormatException e) {
                throw new EXistException("Bad max-nodes option: " + maxNodesOpt);
            }
        }
        DebuggeeFactory.checkForDebugRequest(request, context);
        Sequence resultSequence;
        try {
            resultSequence = xquery.execute(broker, query, null, outputProperties);
        } finally {
            context.runCleanupTasks();
            getPool().getXQueryPool().returnCompiledXQuery(source, query);
        }
        final String mediaType = outputProperties.getProperty(OutputKeys.MEDIA_TYPE);
        if (mediaType != null) {
            if (!response.isCommitted()) {
                if (MimeTable.getInstance().isTextContent(mediaType)) {
                    response.setContentType(mediaType + "; charset=" + getFormEncoding());
                    response.setCharacterEncoding(getFormEncoding());
                } else
                    response.setContentType(mediaType);
            }
        } else {
            String contentType = this.contentType;
            try {
                contentType = getServletContext().getMimeType(path);
                if (contentType == null) {
                    contentType = this.contentType;
                }
            } catch (final Throwable e) {
                contentType = this.contentType;
            } finally {
                if (MimeTable.getInstance().isTextContent(contentType)) {
                    contentType += "; charset=" + getFormEncoding();
                }
                response.setContentType(contentType);
            }
        }
        if (requestAttr != null && (XmldbURI.API_LOCAL.equals(collectionURI.getApiName()))) {
            request.setAttribute(requestAttr, resultSequence);
        } else {
            XQuerySerializer serializer = new XQuerySerializer(broker, outputProperties, output);
            serializer.serialize(resultSequence);
        }
    } catch (final PermissionDeniedException e) {
        if (getDefaultUser().equals(user)) {
            getAuthenticator().sendChallenge(request, response);
        } else {
            response.sendError(HttpServletResponse.SC_FORBIDDEN, "No permission to execute XQuery for: " + path + " denied.");
        }
        return;
    } catch (final XPathException e) {
        final Logger logger = getLog();
        if (logger.isDebugEnabled()) {
            logger.debug(e.getMessage(), e);
        }
        if (reportErrors) {
            writeError(output, e);
        } else {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            sendError(output, "Error", e.getMessage());
        }
    } catch (final Throwable e) {
        getLog().error(e.getMessage(), e);
        if (reportErrors) {
            writeError(output, e);
        } else {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            sendError(output, "Error", e.getMessage());
        }
    }
    output.flush();
    output.close();
}
Also used : XQuerySerializer(org.exist.util.serializer.XQuerySerializer) ServletOutputStream(javax.servlet.ServletOutputStream) AuthenticationException(org.exist.security.AuthenticationException) Properties(java.util.Properties) Logger(org.apache.logging.log4j.Logger) ServletException(javax.servlet.ServletException) Item(org.exist.xquery.value.Item) PrintWriter(java.io.PrintWriter) Path(java.nio.file.Path) HttpSession(javax.servlet.http.HttpSession) EXistException(org.exist.EXistException) IOException(java.io.IOException) Sequence(org.exist.xquery.value.Sequence) Subject(org.exist.security.Subject) ServletException(javax.servlet.ServletException) URISyntaxException(java.net.URISyntaxException) PermissionDeniedException(org.exist.security.PermissionDeniedException) EXistException(org.exist.EXistException) AuthenticationException(org.exist.security.AuthenticationException) IOException(java.io.IOException) DBBroker(org.exist.storage.DBBroker) Descriptor(org.exist.http.Descriptor) OutputStreamWriter(java.io.OutputStreamWriter) PermissionDeniedException(org.exist.security.PermissionDeniedException)

Example 2 with Descriptor

use of org.exist.http.Descriptor in project exist by eXist-db.

the class EXistServlet method doPatch.

protected void doPatch(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
    // first, adjust the path
    String path = adjustPath(request);
    // second, perform descriptor actions
    final Descriptor descriptor = Descriptor.getDescriptorSingleton();
    if (descriptor != null) {
        // TODO: figure out a way to log PATCH requests with
        // HttpServletRequestWrapper and
        // Descriptor.doLogRequestInReplayLog()
        // map's the path if a mapping is specified in the descriptor
        path = descriptor.mapPath(path);
    }
    // third, authenticate the user
    final Subject user = authenticate(request, response);
    if (user == null) {
        // You now get a HTTP Authentication challenge if there is no user
        return;
    }
    // fourth, process the request
    try (final DBBroker broker = getPool().get(Optional.of(user));
        final Txn transaction = getPool().getTransactionManager().beginTransaction()) {
        final XmldbURI dbpath = XmldbURI.createInternal(path);
        try (final Collection collection = broker.getCollection(dbpath)) {
            if (collection != null) {
                transaction.abort();
                response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "A PATCH request is not allowed against a plain collection path.");
                return;
            }
        }
        try {
            srvREST.doPatch(broker, transaction, dbpath, request, response);
            transaction.commit();
        } catch (final Throwable t) {
            transaction.abort();
            throw t;
        }
    } catch (final MethodNotAllowedException e) {
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, e.getMessage());
    } catch (final BadRequestException e) {
        if (response.isCommitted()) {
            throw new ServletException(e.getMessage(), e);
        }
        response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
    } catch (final PermissionDeniedException e) {
        // Else return a FORBIDDEN Error
        if (user.equals(getDefaultUser())) {
            getAuthenticator().sendChallenge(request, response);
        } else {
            response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());
        }
    } catch (final EXistException e) {
        if (response.isCommitted()) {
            throw new ServletException(e.getMessage(), e);
        }
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
    } catch (final Throwable e) {
        LOG.error(e);
        throw new ServletException("An unknown error occurred: " + e.getMessage(), e);
    }
}
Also used : MethodNotAllowedException(org.exist.http.MethodNotAllowedException) Txn(org.exist.storage.txn.Txn) EXistException(org.exist.EXistException) Subject(org.exist.security.Subject) ServletException(javax.servlet.ServletException) DBBroker(org.exist.storage.DBBroker) Descriptor(org.exist.http.Descriptor) Collection(org.exist.collections.Collection) BadRequestException(org.exist.http.BadRequestException) PermissionDeniedException(org.exist.security.PermissionDeniedException) XmldbURI(org.exist.xmldb.XmldbURI)

Example 3 with Descriptor

use of org.exist.http.Descriptor in project exist by eXist-db.

the class XQueryServlet method doPost.

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
    HttpServletRequest request = null;
    try {
        // For POST request, If we are logging the requests we must wrap HttpServletRequest in HttpServletRequestWrapper
        // otherwise we cannot access the POST parameters from the content body of the request!!! - deliriumsky
        final Descriptor descriptor = Descriptor.getDescriptorSingleton();
        if (descriptor != null) {
            if (descriptor.allowRequestLogging()) {
                request = new HttpServletRequestWrapper(() -> (String) getPool().getConfiguration().getProperty(Configuration.BINARY_CACHE_CLASS_PROPERTY), req, getFormEncoding());
            } else {
                request = req;
            }
        } else {
            request = req;
        }
        process(request, response);
    } finally {
        if (request != null && request instanceof HttpServletRequestWrapper) {
            ((HttpServletRequestWrapper) request).close();
        }
    }
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) Descriptor(org.exist.http.Descriptor)

Example 4 with Descriptor

use of org.exist.http.Descriptor in project exist by eXist-db.

the class XQueryServlet method doPut.

// -------------------------------
// doPut and doDelete added by Andrzej Taramina (andrzej@chaeron.com)
// Date: Sept/05/2007
// 
// These methods were added so that you can issue an HTTP PUT or DELETE request and have it serviced by an XQuery.
// NOTE: The XQuery referenced in the target URL of the request will be executed and the PUT/DELETE request will be passed to it
// 
// -------------------------------
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
    HttpServletRequest request = null;
    try {
        // For POST request, If we are logging the requests we must wrap HttpServletRequest in HttpServletRequestWrapper
        // otherwise we cannot access the POST parameters from the content body of the request!!! - deliriumsky
        final Descriptor descriptor = Descriptor.getDescriptorSingleton();
        if (descriptor != null) {
            if (descriptor.allowRequestLogging()) {
                request = new HttpServletRequestWrapper(() -> (String) getPool().getConfiguration().getProperty(Configuration.BINARY_CACHE_CLASS_PROPERTY), req, getFormEncoding());
            } else {
                request = req;
            }
        } else {
            request = req;
        }
        process(request, response);
    } finally {
        if (request != null && request instanceof HttpServletRequestWrapper) {
            ((HttpServletRequestWrapper) request).close();
        }
    }
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) Descriptor(org.exist.http.Descriptor)

Example 5 with Descriptor

use of org.exist.http.Descriptor in project exist by eXist-db.

the class XQueryURLRewrite method service.

@Override
protected void service(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException {
    if (rewriteConfig == null) {
        configure();
        rewriteConfig = new RewriteConfig(this);
    }
    final long start = System.currentTimeMillis();
    if (LOG.isTraceEnabled()) {
        LOG.trace(request.getRequestURI());
    }
    final Descriptor descriptor = Descriptor.getDescriptorSingleton();
    if (descriptor != null && descriptor.requestsFiltered()) {
        final String attr = (String) request.getAttribute("XQueryURLRewrite.forwarded");
        if (attr == null) {
            // logs the request if specified in the descriptor
            descriptor.doLogRequestInReplayLog(request);
            request.setAttribute("XQueryURLRewrite.forwarded", "true");
        }
    }
    Subject user = defaultUser;
    Subject requestUser = HttpAccount.getUserFromServletRequest(request);
    if (requestUser != null) {
        user = requestUser;
    } else {
        // Secondly try basic authentication
        final String auth = request.getHeader("Authorization");
        if (auth != null) {
            requestUser = authenticator.authenticate(request, response, sendChallenge);
            if (requestUser != null) {
                user = requestUser;
            }
        }
    }
    try {
        configure();
        // checkCache(user);
        final RequestWrapper modifiedRequest = new RequestWrapper(request);
        final URLRewrite staticRewrite = rewriteConfig.lookup(modifiedRequest);
        if (staticRewrite != null && !staticRewrite.isControllerForward()) {
            modifiedRequest.setPaths(staticRewrite.resolve(modifiedRequest), staticRewrite.getPrefix());
            if (LOG.isTraceEnabled()) {
                LOG.trace("Forwarding to target: {}", staticRewrite.getTarget());
            }
            staticRewrite.doRewrite(modifiedRequest, response);
        } else {
            if (LOG.isTraceEnabled()) {
                LOG.trace("Processing request URI: {}", request.getRequestURI());
            }
            if (staticRewrite != null) {
                // fix the request URI
                staticRewrite.updateRequest(modifiedRequest);
            }
            // check if the request URI is already in the url cache
            ModelAndView modelView = getFromCache(request.getHeader("Host") + request.getRequestURI(), user);
            if (LOG.isDebugEnabled()) {
                LOG.debug("Checked cache for URI: {} original: {}", modifiedRequest.getRequestURI(), request.getRequestURI());
            }
            // no: create a new model and view configuration
            if (modelView == null) {
                modelView = new ModelAndView();
                // Execute the query
                try (final DBBroker broker = pool.get(Optional.ofNullable(user))) {
                    modifiedRequest.setAttribute(RQ_ATTR_REQUEST_URI, request.getRequestURI());
                    final Properties outputProperties = new Properties();
                    outputProperties.setProperty(OutputKeys.INDENT, "yes");
                    outputProperties.setProperty(OutputKeys.ENCODING, "UTF-8");
                    outputProperties.setProperty(OutputKeys.MEDIA_TYPE, MimeType.XML_TYPE.getName());
                    final Sequence result = runQuery(broker, modifiedRequest, response, modelView, staticRewrite, outputProperties);
                    logResult(broker, result);
                    if (response.isCommitted()) {
                        return;
                    }
                    // process the query result
                    if (result.getItemCount() == 1) {
                        final Item resource = result.itemAt(0);
                        if (!Type.subTypeOf(resource.getType(), Type.NODE)) {
                            throw new ServletException("XQueryURLRewrite: urlrewrite query should return an element!");
                        }
                        Node node = ((NodeValue) resource).getNode();
                        if (node.getNodeType() == Node.DOCUMENT_NODE) {
                            node = ((Document) node).getDocumentElement();
                        }
                        if (node.getNodeType() != Node.ELEMENT_NODE) {
                            // throw new ServletException("Redirect XQuery should return an XML element!");
                            response(broker, response, outputProperties, result);
                            return;
                        }
                        Element elem = (Element) node;
                        final String ns = elem.getNamespaceURI();
                        if (!Namespaces.EXIST_NS.equals(ns)) {
                            response(broker, response, outputProperties, result);
                            return;
                        }
                        final String nsUri = elem.getNamespaceURI();
                        if (Namespaces.EXIST_NS.equals(nsUri) && "dispatch".equals(elem.getLocalName())) {
                            node = elem.getFirstChild();
                            while (node != null) {
                                final String nodeNs = node.getNamespaceURI();
                                if (node.getNodeType() == Node.ELEMENT_NODE && Namespaces.EXIST_NS.equals(nodeNs)) {
                                    final Element action = (Element) node;
                                    if ("view".equals(action.getLocalName())) {
                                        parseViews(modifiedRequest, action, modelView);
                                    } else if ("error-handler".equals(action.getLocalName())) {
                                        parseErrorHandlers(modifiedRequest, action, modelView);
                                    } else if ("cache-control".equals(action.getLocalName())) {
                                        final String option = action.getAttribute("cache");
                                        modelView.setUseCache("yes".equals(option));
                                    } else {
                                        final URLRewrite urw = parseAction(modifiedRequest, action);
                                        if (urw != null) {
                                            modelView.setModel(urw);
                                        }
                                    }
                                }
                                node = node.getNextSibling();
                            }
                            if (modelView.getModel() == null) {
                                modelView.setModel(new PassThrough(config, elem, modifiedRequest));
                            }
                        } else if (nsUri != null && Namespaces.EXIST_NS.equals(elem.getNamespaceURI()) && "ignore".equals(elem.getLocalName())) {
                            modelView.setModel(new PassThrough(config, elem, modifiedRequest));
                            final NodeList nl = elem.getElementsByTagNameNS(Namespaces.EXIST_NS, "cache-control");
                            if (nl.getLength() > 0) {
                                elem = (Element) nl.item(0);
                                final String option = elem.getAttribute("cache");
                                modelView.setUseCache("yes".equals(option));
                            }
                        } else {
                            response(broker, response, outputProperties, result);
                            return;
                        }
                    } else if (result.getItemCount() > 1) {
                        response(broker, response, outputProperties, result);
                        return;
                    }
                    if (modelView.useCache()) {
                        LOG.debug("Caching request to {}", request.getRequestURI());
                        urlCache.put(modifiedRequest.getHeader("Host") + request.getRequestURI(), modelView);
                    }
                }
                // store the original request URI to org.exist.forward.request-uri
                modifiedRequest.setAttribute(RQ_ATTR_REQUEST_URI, request.getRequestURI());
                modifiedRequest.setAttribute(RQ_ATTR_SERVLET_PATH, request.getServletPath());
            }
            if (LOG.isTraceEnabled()) {
                LOG.trace("URLRewrite took {}ms.", System.currentTimeMillis() - start);
            }
            final HttpServletResponse wrappedResponse = new CachingResponseWrapper(response, modelView.hasViews() || modelView.hasErrorHandlers());
            if (modelView.getModel() == null) {
                modelView.setModel(new PassThrough(config, modifiedRequest));
            }
            if (staticRewrite != null) {
                if (modelView.getModel().doResolve()) {
                    staticRewrite.rewriteRequest(modifiedRequest);
                } else {
                    modelView.getModel().setAbsolutePath(modifiedRequest);
                }
            }
            modifiedRequest.allowCaching(!modelView.hasViews());
            doRewrite(modelView.getModel(), modifiedRequest, wrappedResponse);
            final int status = wrappedResponse.getStatus();
            if (status == HttpServletResponse.SC_NOT_MODIFIED) {
                response.flushBuffer();
            } else if (status < HttpServletResponse.SC_BAD_REQUEST) {
                if (modelView.hasViews()) {
                    applyViews(modelView, modelView.views, response, modifiedRequest, wrappedResponse);
                } else {
                    ((CachingResponseWrapper) wrappedResponse).flush();
                }
            } else {
                // HTTP response code indicates an error
                if (modelView.hasErrorHandlers()) {
                    final byte[] data = ((CachingResponseWrapper) wrappedResponse).getData();
                    if (data != null) {
                        modifiedRequest.setAttribute(RQ_ATTR_ERROR, new String(data, UTF_8));
                    }
                    applyViews(modelView, modelView.errorHandlers, response, modifiedRequest, wrappedResponse);
                } else {
                    flushError(response, wrappedResponse);
                }
            }
        }
    } catch (final Throwable e) {
        LOG.error("Error while processing {}: {}", request.getRequestURI(), e.getMessage(), e);
        throw new ServletException("An error occurred while processing request to " + request.getRequestURI() + ": " + e.getMessage(), e);
    }
}
Also used : NodeValue(org.exist.xquery.value.NodeValue) Node(org.w3c.dom.Node) Element(org.w3c.dom.Element) NodeList(org.w3c.dom.NodeList) HttpServletResponse(javax.servlet.http.HttpServletResponse) Sequence(org.exist.xquery.value.Sequence) Subject(org.exist.security.Subject) Item(org.exist.xquery.value.Item) DBBroker(org.exist.storage.DBBroker) Descriptor(org.exist.http.Descriptor) HttpRequestWrapper(org.exist.http.servlets.HttpRequestWrapper)

Aggregations

Descriptor (org.exist.http.Descriptor)11 ServletException (javax.servlet.ServletException)8 EXistException (org.exist.EXistException)8 Subject (org.exist.security.Subject)8 DBBroker (org.exist.storage.DBBroker)8 PermissionDeniedException (org.exist.security.PermissionDeniedException)7 Txn (org.exist.storage.txn.Txn)6 BadRequestException (org.exist.http.BadRequestException)5 NotFoundException (org.exist.http.NotFoundException)4 HttpServletRequest (javax.servlet.http.HttpServletRequest)3 Collection (org.exist.collections.Collection)2 XmldbURI (org.exist.xmldb.XmldbURI)2 Item (org.exist.xquery.value.Item)2 Sequence (org.exist.xquery.value.Sequence)2 EOFException (java.io.EOFException)1 IOException (java.io.IOException)1 OutputStreamWriter (java.io.OutputStreamWriter)1 PrintWriter (java.io.PrintWriter)1 URISyntaxException (java.net.URISyntaxException)1 Path (java.nio.file.Path)1