1 /*
2  * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.sun.net.httpserver;
27 
28 import java.io.IOException;
29 import java.util.*;
30 
31 /**
32  * A filter used to pre- and post-process incoming requests. Pre-processing occurs
33  * before the application's exchange handler is invoked, and post-processing
34  * occurs after the exchange handler returns.  Filters
35  * are organised in chains, and are associated with HttpContext instances.
36  * <p>
37  * Each Filter in the chain, invokes the next filter within its own
38  * doFilter() implementation. The final Filter in the chain invokes the applications
39  * exchange handler.
40  * @since 1.6
41  */
42 public abstract class Filter {
43 
Filter()44     protected Filter () {}
45 
46     /**
47      * a chain of filters associated with a HttpServer.
48      * Each filter in the chain is given one of these
49      * so it can invoke the next filter in the chain
50      */
51     public static class Chain {
52         /* the last element in the chain must invoke the users
53          * handler
54          */
55         private ListIterator<Filter> iter;
56         private HttpHandler handler;
57 
Chain(List<Filter> filters, HttpHandler handler)58         public Chain (List<Filter> filters, HttpHandler handler) {
59             iter = filters.listIterator();
60             this.handler = handler;
61         }
62 
63         /**
64          * calls the next filter in the chain, or else
65          * the users exchange handler, if this is the
66          * final filter in the chain. The Filter may decide
67          * to terminate the chain, by not calling this method.
68          * In this case, the filter <b>must</b> send the
69          * response to the request, because the application's
70          * exchange handler will not be invoked.
71          * @param exchange the HttpExchange
72          * @throws IOException let exceptions pass up the stack
73          * @throws NullPointerException if exchange is {@code null}
74          */
doFilter(HttpExchange exchange)75         public void doFilter (HttpExchange exchange) throws IOException {
76             if (!iter.hasNext()) {
77                 handler.handle (exchange);
78             } else {
79                 Filter f = iter.next();
80                 f.doFilter (exchange, this);
81             }
82         }
83     }
84 
85     /**
86      * Asks this filter to pre/post-process the given exchange. The filter
87      * can:
88      * <ul><li>examine or modify the request headers</li>
89      * <li>filter the request body or the response body, by creating suitable
90      * filter streams and calling
91      * {@link HttpExchange#setStreams(InputStream,OutputStream)}</li>
92      * <li>set attribute Objects in the exchange, which other filters or the
93      * exchange handler can access.</li>
94      * <li>decide to either<ol>
95      * <li>invoke the next filter in the chain, by calling
96      * {@link Filter.Chain#doFilter(HttpExchange)}</li>
97      * <li>terminate the chain of invocation, by <b>not</b> calling
98      * {@link Filter.Chain#doFilter(HttpExchange)}</li></ol>
99      * <li>if option 1. above taken, then when doFilter() returns all subsequent
100      * filters in the Chain have been called, and the response headers can be
101      * examined or modified.</li>
102      * <li>if option 2. above taken, then this Filter must use the HttpExchange
103      * to send back an appropriate response</li></ul>
104      *
105      * @param exchange the {@code HttpExchange} to be filtered.
106      * @param chain the Chain which allows the next filter to be invoked.
107      * @throws IOException may be thrown by any filter module, and if
108      *          caught, must be rethrown again.
109      * @throws NullPointerException if either exchange or chain are {@code null}
110      */
doFilter(HttpExchange exchange, Chain chain)111     public abstract void doFilter (HttpExchange exchange, Chain chain)
112         throws IOException;
113 
114     /**
115      * returns a short description of this Filter
116      * @return a string describing the Filter
117      */
description()118     public abstract String description ();
119 
120 }
121