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.AsyncEvent;
24import javax.servlet.AsyncListener;
25import javax.servlet.ServletException;
26import javax.servlet.http.HttpServletRequest;
27import javax.servlet.http.HttpServletResponse;
28
29import org.eclipse.jetty.io.EndPoint;
30import org.eclipse.jetty.server.AbstractHttpConnection;
31import org.eclipse.jetty.server.Request;
32
33/**
34 * Handler to adjust the idle timeout of requests while dispatched.
35 *
36 * <p>Can be applied in jetty.xml with
37 * <pre>
38 *   &lt;Get id='handler' name='Handler'/>
39 *   &lt;Set name='Handler'>
40 *     &lt;New id='idleTimeoutHandler' class='org.eclipse.jetty.server.handler.IdleTimeoutHandler'>
41 *       &lt;Set name='Handler'>&lt;Ref id='handler'/>&lt;/Set>
42 *       &lt;Set name='IdleTimeoutMs'>5000&lt;/Set>
43 *     &lt;/New>
44 *   &lt;/Set>
45 * </pre>
46 */
47public class IdleTimeoutHandler extends HandlerWrapper
48{
49    private int _idleTimeoutMs = 1000;
50    private boolean _applyToAsync = false;
51
52
53    public boolean isApplyToAsync()
54    {
55        return _applyToAsync;
56    }
57
58    /**
59     * Should the adjusted idle time be maintained for asynchronous requests
60     * @param applyToAsync true if alternate idle timeout is applied to asynchronous requests
61     */
62    public void setApplyToAsync(boolean applyToAsync)
63    {
64        _applyToAsync = applyToAsync;
65    }
66
67    public long getIdleTimeoutMs()
68    {
69        return _idleTimeoutMs;
70    }
71
72    /**
73     * @param idleTimeoutMs The idle timeout in MS to apply while dispatched or async
74     */
75    public void setIdleTimeoutMs(int _idleTimeoutMs)
76    {
77        this._idleTimeoutMs = _idleTimeoutMs;
78    }
79
80
81    @Override
82    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
83    {
84        AbstractHttpConnection connection = AbstractHttpConnection.getCurrentConnection();
85        final EndPoint endp = connection==null?null:connection.getEndPoint();
86
87        final int idle_timeout;
88        if (endp==null)
89            idle_timeout=-1;
90        else
91        {
92            idle_timeout=endp.getMaxIdleTime();
93            endp.setMaxIdleTime(_idleTimeoutMs);
94        }
95
96        try
97        {
98            super.handle(target,baseRequest,request,response);
99        }
100        finally
101        {
102            if (endp!=null)
103            {
104                if (_applyToAsync && request.isAsyncStarted())
105                {
106                    request.getAsyncContext().addListener(new AsyncListener()
107                    {
108                        @Override
109                        public void onTimeout(AsyncEvent event) throws IOException
110                        {
111                        }
112
113                        @Override
114                        public void onStartAsync(AsyncEvent event) throws IOException
115                        {
116                        }
117
118                        @Override
119                        public void onError(AsyncEvent event) throws IOException
120                        {
121                            endp.setMaxIdleTime(idle_timeout);
122                        }
123
124                        @Override
125                        public void onComplete(AsyncEvent event) throws IOException
126                        {
127                            endp.setMaxIdleTime(idle_timeout);
128                        }
129                    });
130                }
131                else
132                {
133                    endp.setMaxIdleTime(idle_timeout);
134                }
135            }
136        }
137    }
138}
139