1 //
2 // ========================================================================
3 // Copyright (c) 1995-2016 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
19 package org.eclipse.jetty.server;
20
21 import java.util.Set;
22
23 import javax.servlet.http.Cookie;
24 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.http.HttpServletResponse;
26 import javax.servlet.http.HttpSession;
27
28 /** Build a request to be pushed.
29 * <p>
30 * A PushBuilder is obtained by calling {@link Request#getPushBuilder()}
31 * which creates an initializes the builder as follows:
32 * <ul>
33 * <li> Each call to getPushBuilder() will return a new instance of a
34 * PushBuilder based off the Request. Any mutations to the
35 * returned PushBuilder are not reflected on future returns.</li>
36 * <li>The method is initialized to "GET"</li>
37 * <li>The requests headers are added to the Builder, except for:<ul>
38 * <li>Conditional headers (eg. If-Modified-Since)
39 * <li>Range headers
40 * <li>Expect headers
41 * <li>Authorization headers
42 * <li>Referrer headers
43 * </ul></li>
44 * <li>If the request was Authenticated, an Authorization header will
45 * be set with a container generated token that will result in equivalent
46 * Authorization for the pushed request</li>
47 * <li>The query string from {@link HttpServletRequest#getQueryString()}
48 * <li>The {@link HttpServletRequest#getRequestedSessionId()} value, unless at the time
49 * of the call {@link HttpServletRequest#getSession(boolean)}
50 * has previously been called to create a new {@link HttpSession}, in
51 * which case the new session ID will be used as the PushBuilders
52 * requested session ID. The source of the requested session id will be the
53 * same as for the request</li>
54 * <li>The Referer header will be set to {@link HttpServletRequest#getRequestURL()}
55 * plus any {@link HttpServletRequest#getQueryString()} </li>
56 * <li>If {@link HttpServletResponse#addCookie(Cookie)} has been called
57 * on the associated response, then a corresponding Cookie header will be added
58 * to the PushBuilder, unless the {@link Cookie#getMaxAge()} is <=0, in which
59 * case the Cookie will be removed from the builder.</li>
60 * <li>If this request has has the conditional headers If-Modified-Since or
61 * If-None-Match then the {@link #isConditional()} header is set to true.</li>
62 * </ul>
63 * <p>A PushBuilder can be customized by chained calls to mutator methods before the
64 * {@link #push()} method is called to initiate a push request with the current state
65 * of the builder. After the call to {@link #push()}, the builder may be reused for
66 * another push, however the {@link #path(String)}, {@link #etag(String)} and
67 * {@link #lastModified(String)} values will have been nulled. All other
68 * values are retained over calls to {@link #push()}.
69 */
70 public interface PushBuilder
71 {
72 /** Set the method to be used for the push.
73 * Defaults to GET.
74 * @param method the method to be used for the push.
75 * @return this builder.
76 */
77 public abstract PushBuilder method(String method);
78
79 /** Set the query string to be used for the push.
80 * Defaults to the requests query string.
81 * Will be appended to any query String included in a call to {@link #path(String)}. This
82 * method should be used instead of a query in {@link #path(String)} when multiple
83 * {@link #push()} calls are to be made with the same query string, or to remove a
84 * query string obtained from the associated request.
85 * @param queryString the query string to be used for the push.
86 * @return this builder.
87 */
88 public abstract PushBuilder queryString(String queryString);
89
90 /** Set the SessionID to be used for the push.
91 * The session ID will be set in the same way it was on the associated request (ie
92 * as a cookie if the associated request used a cookie, or as a url parameter if
93 * the associated request used a url parameter).
94 * Defaults to the requested session ID or any newly assigned session id from
95 * a newly created session.
96 * @param sessionId the SessionID to be used for the push.
97 * @return this builder.
98 */
99 public abstract PushBuilder sessionId(String sessionId);
100
101 /** Set if the request is to be conditional.
102 * If the request is conditional, any available values from {@link #etag(String)} or
103 * {@link #lastModified(String)} will be set in the appropriate headers. If the request
104 * is not conditional, then etag and lastModified values are ignored.
105 * Defaults to true if the associated request was conditional.
106 * @param conditional true if the push request is conditional
107 * @return this builder.
108 */
109 public abstract PushBuilder conditional(boolean conditional);
110
111 /** Set a header to be used for the push.
112 * @param name The header name to set
113 * @param value The header value to set
114 * @return this builder.
115 */
116 public abstract PushBuilder setHeader(String name, String value);
117
118 /** Add a header to be used for the push.
119 * @param name The header name to add
120 * @param value The header value to add
121 * @return this builder.
122 */
123 public abstract PushBuilder addHeader(String name, String value);
124
125 /** Set the URI path to be used for the push.
126 * The path may start with "/" in which case it is treated as an
127 * absolute path, otherwise it is relative to the context path of
128 * the associated request.
129 * There is no path default and {@link #path(String)} must be called
130 * before every call to {@link #push()}
131 * @param path the URI path to be used for the push, which may include a
132 * query string.
133 * @return this builder.
134 */
135 public abstract PushBuilder path(String path);
136
137 /** Set the etag to be used for conditional pushes.
138 * The etag will be used only if {@link #isConditional()} is true.
139 * Defaults to no etag. The value is nulled after every call to
140 * {@link #push()}
141 * @param etag the etag to be used for the push.
142 * @return this builder.
143 */
144 public abstract PushBuilder etag(String etag);
145
146 /** Set the last modified date to be used for conditional pushes.
147 * The last modified date will be used only if {@link #isConditional()} is true.
148 * Defaults to no date. The value is nulled after every call to
149 * {@link #push()}
150 * @param lastModified the last modified date to be used for the push.
151 * @return this builder.
152 * */
153 public abstract PushBuilder lastModified(String lastModified);
154
155
156 /** Push a resource.
157 * Push a resource based on the current state of the PushBuilder. If {@link #isConditional()}
158 * is true and an etag or lastModified value is provided, then an appropriate conditional header
159 * will be generated. If both an etag and lastModified value are provided only an If-None-Match header
160 * will be generated. If the builder has a session ID, then the pushed request
161 * will include the session ID either as a Cookie or as a URI parameter as appropriate. The builders
162 * query string is merged with any passed query string.
163 * After initiating the push, the builder has its path, etag and lastModified fields nulled. All
164 * other fields are left as is for possible reuse in another push.
165 * @throws IllegalArgumentException if the method set expects a request body (eg POST)
166 */
167 public abstract void push();
168
169
170
171
172
173 public abstract String getMethod();
174 public abstract String getQueryString();
175 public abstract String getSessionId();
176 public abstract boolean isConditional();
177 public abstract Set<String> getHeaderNames();
178 public abstract String getHeader(String name);
179 public abstract String getPath();
180 public abstract String getEtag();
181 public abstract String getLastModified();
182
183
184
185 }