1//
2//  ========================================================================
3//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4//  ------------------------------------------------------------------------
5//  All rights reserved. This program and the accompanying materials
6//  are made available under the terms of the Eclipse Public License v1.0
7//  and Apache License v2.0 which accompanies this distribution.
8//
9//      The Eclipse Public License is available at
10//      http://www.eclipse.org/legal/epl-v10.html
11//
12//      The Apache License v2.0 is available at
13//      http://www.opensource.org/licenses/apache2.0.php
14//
15//  You may elect to redistribute this code under either of these licenses.
16//  ========================================================================
17//
18
19package org.eclipse.jetty.server.handler;
20
21import java.io.IOException;
22
23import javax.servlet.ServletException;
24import javax.servlet.http.HttpServletRequest;
25import javax.servlet.http.HttpServletResponse;
26
27import org.eclipse.jetty.http.HttpHeaders;
28import org.eclipse.jetty.server.HandlerContainer;
29import org.eclipse.jetty.server.Request;
30import org.eclipse.jetty.util.URIUtil;
31
32/* ------------------------------------------------------------ */
33/** Moved ContextHandler.
34 * This context can be used to replace a context that has changed
35 * location.  Requests are redirected (either to a fixed URL or to a
36 * new context base).
37 */
38public class MovedContextHandler extends ContextHandler
39{
40    final Redirector _redirector;
41    String _newContextURL;
42    boolean _discardPathInfo;
43    boolean _discardQuery;
44    boolean _permanent;
45    String _expires;
46
47    public MovedContextHandler()
48    {
49        _redirector=new Redirector();
50        setHandler(_redirector);
51        setAllowNullPathInfo(true);
52    }
53
54    public MovedContextHandler(HandlerContainer parent, String contextPath, String newContextURL)
55    {
56        super(parent,contextPath);
57        _newContextURL=newContextURL;
58        _redirector=new Redirector();
59        setHandler(_redirector);
60    }
61
62    public boolean isDiscardPathInfo()
63    {
64        return _discardPathInfo;
65    }
66
67    public void setDiscardPathInfo(boolean discardPathInfo)
68    {
69        _discardPathInfo = discardPathInfo;
70    }
71
72    public String getNewContextURL()
73    {
74        return _newContextURL;
75    }
76
77    public void setNewContextURL(String newContextURL)
78    {
79        _newContextURL = newContextURL;
80    }
81
82    public boolean isPermanent()
83    {
84        return _permanent;
85    }
86
87    public void setPermanent(boolean permanent)
88    {
89        _permanent = permanent;
90    }
91
92    public boolean isDiscardQuery()
93    {
94        return _discardQuery;
95    }
96
97    public void setDiscardQuery(boolean discardQuery)
98    {
99        _discardQuery = discardQuery;
100    }
101
102    private class Redirector extends AbstractHandler
103    {
104        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
105        {
106            if (_newContextURL==null)
107                return;
108
109            String path=_newContextURL;
110            if (!_discardPathInfo && request.getPathInfo()!=null)
111                path=URIUtil.addPaths(path, request.getPathInfo());
112
113            StringBuilder location = URIUtil.hasScheme(path)?new StringBuilder():baseRequest.getRootURL();
114
115            location.append(path);
116            if (!_discardQuery && request.getQueryString()!=null)
117            {
118                location.append('?');
119                String q=request.getQueryString();
120                q=q.replaceAll("\r\n?&=","!");
121                location.append(q);
122            }
123
124            response.setHeader(HttpHeaders.LOCATION,location.toString());
125
126            if (_expires!=null)
127                response.setHeader(HttpHeaders.EXPIRES,_expires);
128
129            response.setStatus(_permanent?HttpServletResponse.SC_MOVED_PERMANENTLY:HttpServletResponse.SC_FOUND);
130            response.setContentLength(0);
131            baseRequest.setHandled(true);
132        }
133
134    }
135
136    /* ------------------------------------------------------------ */
137    /**
138     * @return the expires header value or null if no expires header
139     */
140    public String getExpires()
141    {
142        return _expires;
143    }
144
145    /* ------------------------------------------------------------ */
146    /**
147     * @param expires the expires header value or null if no expires header
148     */
149    public void setExpires(String expires)
150    {
151        _expires = expires;
152    }
153
154}
155