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
26package com.sun.net.httpserver;
27
28import java.io.IOException;
29import 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 */
42public abstract class Filter {
43
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
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         */
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     */
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     */
118    public abstract String description ();
119
120}
121