/******************************************************************************* * Copyright (c) 2010, 2014 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.orion.internal.server.servlets; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.orion.internal.server.servlets.file.NewFileServlet; import org.eclipse.orion.internal.server.sftpfile.AuthCoreException; import org.eclipse.orion.server.core.ProtocolConstants; /** * A servlet resource handler processes an HTTP request for a given resource. * The handler is given a resource object that has been constructed based on the * request URL and headers. The handler is responsible for filling in the response content type, headers, * and body as appropriate for a given result object. * * @param <T> The type of resource this handler processes. */ public abstract class ServletResourceHandler<T> { /** * An enumeration of the HTTP method types. */ public enum Method { GET, HEAD, OPTIONS, POST, PUT, DELETE; /** * Convenience method to convert an HTTP method string into an * enumerated type. */ public static Method fromString(String methodName) { if ("GET".equals(methodName)) //$NON-NLS-1$ return GET; if ("PUT".equals(methodName)) //$NON-NLS-1$ return PUT; if ("POST".equals(methodName)) //$NON-NLS-1$ return POST; if ("HEAD".equals(methodName)) //$NON-NLS-1$ return HEAD; if ("OPTIONS".equals(methodName)) //$NON-NLS-1$ return OPTIONS; if ("DELETE".equals(methodName)) //$NON-NLS-1$ return DELETE; return null; } } /** * Convenience method to convert an HTTP method string into an * enumerated type. */ public static Method getMethod(HttpServletRequest request) { return Method.fromString(request.getMethod()); } /** * Convenience method to obtain the URI of the request */ public static URI getURI(HttpServletRequest request) { String path = request.getServletPath(); String pathInfo = request.getPathInfo(); if (pathInfo != null) { path += request.getPathInfo(); } try { // Note: no query string! return new URI("orion", null, path, null, null); } catch (URISyntaxException e) { //location not properly encoded return null; } } public static URI resovleOrionURI(HttpServletRequest request, URI uri) { if (!uri.getScheme().equals("orion")) return uri; try { return new URI(null, null, request.getContextPath() + uri.getPath(), uri.getQuery(), uri.getFragment()); } catch (URISyntaxException e) { //location not properly encoded return null; } } public static String toOrionLocation(HttpServletRequest request, String location) { String contextPath = request.getContextPath(); if (location != null && contextPath.length() != 0 && location.startsWith(contextPath)) { location = location.substring(contextPath.length()); } return location; } /** * Handles the given HTTP request for the provided resource. * * @param request The HTTP request object * @param response The servlet response object * @param object The object that is the target resource for the request */ public abstract boolean handleRequest(HttpServletRequest request, HttpServletResponse response, T object) throws ServletException; /** * Checks if the provided exception is an authentication failure. If so, it configures the appropriate * response and returns <code>true</code>. If the exception is not an authentication * failure this method takes no action and returns <code>false</code>. */ protected boolean handleAuthFailure(HttpServletRequest request, HttpServletResponse response, Exception e) { if (e instanceof AuthCoreException) { String realm = ((AuthCoreException) e).getRealm(); response.setHeader(ProtocolConstants.HEADER_WWW_AUTHENTICATE, "Basic realm=\"" + realm + "\""); //$NON-NLS-1$ //$NON-NLS-2$ try { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); return true; } catch (IOException ioException) { //return false below and let caller handle as general error } } //not an authentication failure return false; } /** * Maps the client-facing location URL of a file or directory back to the local * file system path on the server. Returns <code>null</code> if the * location could not be resolved to a local file system location. */ protected IFileStore resolveSourceLocation(HttpServletRequest request, String locationString) throws URISyntaxException { URI sourceLocation = new URI(locationString); //resolve relative URI against request URI String sourcePath = sourceLocation.getPath().substring(request.getContextPath().length()); //first segment is the servlet path IPath path = new Path(sourcePath).removeFirstSegments(1); return NewFileServlet.getFileStore(request, path); } }