001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 * Contributors: 020 * Florent Guillaume 021 */ 022package org.nuxeo.ecm.core.opencmis.bindings; 023 024import java.io.IOException; 025import java.io.PrintWriter; 026 027import javax.servlet.ServletException; 028import javax.servlet.http.HttpServletRequest; 029import javax.servlet.http.HttpServletResponse; 030 031import org.apache.chemistry.opencmis.server.impl.atompub.AbstractAtomPubServiceCall; 032import org.apache.chemistry.opencmis.server.impl.atompub.CmisAtomPubServlet; 033import org.apache.chemistry.opencmis.server.shared.Dispatcher; 034import org.apache.chemistry.opencmis.server.shared.ExceptionHelper; 035import org.apache.commons.lang.StringEscapeUtils; 036import org.apache.commons.lang.StringUtils; 037import org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisErrorHelper.ErrorInfo; 038import org.nuxeo.ecm.platform.web.common.vh.VirtualHostHelper; 039import org.slf4j.Logger; 040import org.slf4j.LoggerFactory; 041 042/** 043 * Subclass CmisAtomPubServlet to inject a virtual-hosted base URL if needed. 044 */ 045public class NuxeoCmisAtomPubServlet extends CmisAtomPubServlet { 046 047 private static final long serialVersionUID = 1L; 048 049 private static final Logger LOG = LoggerFactory.getLogger(NuxeoCmisAtomPubServlet.class); 050 051 @Override 052 protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, 053 IOException { 054 String baseUrl = VirtualHostHelper.getBaseURL(request); 055 if (baseUrl != null) { 056 baseUrl = StringUtils.stripEnd(baseUrl, "/") + request.getServletPath() + "/" 057 + AbstractAtomPubServiceCall.REPOSITORY_PLACEHOLDER + "/"; 058 request.setAttribute(Dispatcher.BASE_URL_ATTRIBUTE, baseUrl); 059 } 060 super.service(request, response); 061 } 062 063 /** 064 * Extracts the error from the exception. 065 * 066 * @param ex the exception 067 * @return the error info 068 * @since 7.1 069 */ 070 protected ErrorInfo extractError(Exception ex) { 071 return NuxeoCmisErrorHelper.extractError(ex); 072 } 073 074 @Override 075 protected void printError(Exception ex, HttpServletRequest request, HttpServletResponse response) { 076 ErrorInfo errorInfo = extractError(ex); 077 if (response.isCommitted()) { 078 LOG.warn("Failed to send error message to client. " + "Response is already committed.", ex); 079 return; 080 } 081 082 try { 083 response.resetBuffer(); 084 response.setStatus(errorInfo.statusCode); 085 response.setContentType("text/html"); 086 response.setCharacterEncoding("UTF-8"); 087 088 PrintWriter pw = response.getWriter(); 089 090 pw.print("<html><head><title>Apache Chemistry OpenCMIS - " 091 + errorInfo.exceptionName 092 + " error</title>" 093 + "<style><!--H1 {font-size:24px;line-height:normal;font-weight:bold;background-color:#f0f0f0;color:#003366;border-bottom:1px solid #3c78b5;padding:2px;} " 094 + "BODY {font-family:Verdana,arial,sans-serif;color:black;font-size:14px;} " 095 + "HR {color:#3c78b5;height:1px;}--></style></head><body>"); 096 pw.print("<h1>HTTP Status " + errorInfo.statusCode + " - <!--exception-->" + errorInfo.exceptionName 097 + "<!--/exception--></h1>"); 098 pw.print("<p><!--message-->" + StringEscapeUtils.escapeHtml(errorInfo.message) + "<!--/message--></p>"); 099 100 String st = ExceptionHelper.getStacktraceAsString(ex); 101 if (st != null) { 102 pw.print("<hr noshade='noshade'/><!--stacktrace--><pre>\n" + st 103 + "\n</pre><!--/stacktrace--><hr noshade='noshade'/>"); 104 } 105 106 pw.print("</body></html>"); 107 } catch (IOException e) { 108 LOG.error(e.getMessage(), e); 109 try { 110 response.sendError(errorInfo.statusCode, errorInfo.message); 111 } catch (IOException en) { 112 // there is nothing else we can do 113 } 114 } 115 } 116 117}