001// Licensed under the Apache License, Version 2.0 (the "License");
002// you may not use this file except in compliance with the License.
003// You may obtain a copy of the License at
004//
005// http://www.apache.org/licenses/LICENSE-2.0
006//
007// Unless required by applicable law or agreed to in writing, software
008// distributed under the License is distributed on an "AS IS" BASIS,
009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
010// See the License for the specific language governing permissions and
011// limitations under the License.
012package org.apache.tapestry5.http.internal.services;
013
014import java.io.IOException;
015import java.util.Optional;
016
017import javax.servlet.http.HttpServletRequest;
018import javax.servlet.http.HttpServletResponse;
019
020import org.apache.tapestry5.http.CorsHandlerResult;
021import org.apache.tapestry5.http.services.CorsHandler;
022import org.apache.tapestry5.http.services.CorsHandlerHelper;
023
024/**
025 * <p>
026 * Default {@link CorsHandler} implementation. It will process all requests with an Origin HTTP header,
027 * regardless of path. It will also perform preflight requests if 
028 * {@link CorsHandlerHelper#isPreflight(HttpServletRequest)}
029 * returns <code>true</code>. Most logic is delegated is {@link CorsHandlerHelper}.
030 * <p>
031 * <p>
032 * This implementation is inspired by the cors NPM module.
033 * </p>
034 * @see CorsHandlerHelper
035 * @since 5.8.2
036 */
037public class DefaultCorsHandler implements CorsHandler 
038{
039    
040    private final CorsHandlerHelper helper;
041
042    public DefaultCorsHandler(CorsHandlerHelper helper) 
043    {
044        this.helper = helper;
045    }
046
047    @Override
048    public CorsHandlerResult handle(HttpServletRequest request, HttpServletResponse response) throws IOException 
049    {
050        
051        CorsHandlerResult result = CorsHandlerResult.CONTINUE_CORS_PROCESSING;
052        final Optional<String> allowedOrigin = helper.getAllowedOrigin(request);
053        if (helper.isPreflight(request))
054        {
055            if (allowedOrigin.isPresent())
056            {
057                helper.configureOrigin(response, allowedOrigin.get());
058                helper.configureCredentials(response);
059                helper.configureExposeHeaders(response);
060                helper.configureMethods(response);
061                helper.configureAllowedHeaders(response, request);
062                helper.configureMaxAge(response);
063                response.setContentLength(0);
064                response.setStatus(HttpServletResponse.SC_NO_CONTENT);
065                result = CorsHandlerResult.STOP_REQUEST_PROCESSING;
066            }
067        }
068        else if (allowedOrigin.isPresent())
069        {
070            helper.configureOrigin(response, allowedOrigin.get());
071            helper.configureCredentials(response);
072            helper.configureExposeHeaders(response);
073        }
074        return result;
075    }
076
077}