-
Notifications
You must be signed in to change notification settings - Fork 78
/
PushBuilder.java
246 lines (230 loc) · 9.34 KB
/
PushBuilder.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/*
* Copyright (c) 2017, 2023 Oracle and/or its affiliates and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package jakarta.servlet.http;
import java.util.Set;
/**
* Build a request to be pushed.
*
* According section 8.2 of RFC 7540, a promised request must be cacheable and safe without a request body.
*
* <p>
* A PushBuilder is obtained by calling {@link HttpServletRequest#newPushBuilder()}. Each call to this method will a new
* instance of a PushBuilder based off the current {@code
* HttpServletRequest}, or null. Any mutations to the returned PushBuilder are not reflected on future returns.
* </p>
*
* <p>
* The instance is initialized as follows:
* </p>
*
* <ul>
*
* <li>The method is initialized to "GET"</li>
*
* <li>The existing request headers of the current {@link HttpServletRequest} are added to the builder, except for:
*
* <ul>
* <li>Conditional headers (defined in RFC 7232)
* <li>Range headers
* <li>Expect headers
* <li>Authorization headers
* <li>Referrer headers
* </ul>
*
* </li>
*
* <li>If the request was authenticated, an Authorization header will be set with a container generated token that will
* result in equivalent Authorization for the pushed request.</li>
*
* <li>The session ID will be the value returned from {@link HttpServletRequest#getRequestedSessionId()}, unless
* {@link HttpServletRequest#getSession(boolean)} has previously been called to create a new {@link HttpSession} prior
* to the call to create the {@code PushBuilder}, in which case the new session ID will be used as the PushBuilder's
* requested session ID. Note that the session ID returned from the request can effectively come from one of two
* "sources": a cookie or the URL (as specified in {@link HttpServletRequest#isRequestedSessionIdFromCookie} and
* {@link HttpServletRequest#isRequestedSessionIdFromURL}, respectively). The session ID for the {@code PushBuilder}
* will also come from the same source as the request.</li>
*
* <li>The Referer(sic) header will be set to {@link HttpServletRequest#getRequestURL()} plus any
* {@link HttpServletRequest#getQueryString()}</li>
*
* <li>If {@link HttpServletResponse#addCookie(Cookie)} has been called on the associated response, then a corresponding
* Cookie header will be added to the PushBuilder, unless the {@link Cookie#getMaxAge()} is <=0, in which case the
* Cookie will be removed from the builder.</li>
*
* </ul>
*
* <p>
* The {@link #path} method must be called on the {@code PushBuilder} instance before the call to {@link #push}. Failure
* to do so must cause an exception to be thrown from {@link #push}, as specified in that method.
* </p>
*
* <p>
* A PushBuilder can be customized by chained calls to mutator methods before the {@link #push()} method is called to
* initiate an asynchronous push request with the current state of the builder. After the call to {@link #push()}, the
* builder may be reused for another push, however the implementation must make it so the {@link #path(String)} and
* conditional headers (defined in RFC 7232) values are cleared before returning from {@link #push}. All other values
* are retained over calls to {@link #push()}.
*
* @since Servlet 4.0
*
* @deprecated In favor of 103 early hints
*/
@Deprecated
public interface PushBuilder {
/**
* <p>
* Set the method to be used for the push.
* </p>
*
* @param method the method to be used for the push.
*
* @throws NullPointerException if the argument is {@code null}
*
* @throws IllegalArgumentException if the argument is the empty String, or any non-cacheable or unsafe methods defined
* in RFC 7231, which are POST, PUT, DELETE, CONNECT, OPTIONS and TRACE.
*
* @return this builder.
*/
public PushBuilder method(String method);
/**
* Set the query string to be used for the push.
*
* The query string will be appended to any query String included in a call to {@link #path(String)}. Any duplicate
* parameters must be preserved. This method should be used instead of a query in {@link #path(String)} when multiple
* {@link #push()} calls are to be made with the same query string.
*
* @param queryString the query string to be used for the push.
* @return this builder.
*/
public PushBuilder queryString(String queryString);
/**
* Set the SessionID to be used for the push. The session ID will be set in the same way it was on the associated
* request (ie as a cookie if the associated request used a cookie, or as a url parameter if the associated request used
* a url parameter). Defaults to the requested session ID or any newly assigned session id from a newly created session.
*
* @param sessionId the SessionID to be used for the push.
* @return this builder.
*/
public PushBuilder sessionId(String sessionId);
/**
* <p>
* Set a request header to be used for the push. If the builder has an existing header with the same name, its value is
* overwritten.
* </p>
*
* @param name The header name to set
* @param value The header value to set
* @return this builder.
*/
public PushBuilder setHeader(String name, String value);
/**
* <p>
* Add a request header to be used for the push.
* </p>
*
* @param name The header name to add
* @param value The header value to add
* @return this builder.
*/
public PushBuilder addHeader(String name, String value);
/**
* <p>
* Remove the named request header. If the header does not exist, take no action.
* </p>
*
* @param name The name of the header to remove
* @return this builder.
*/
public PushBuilder removeHeader(String name);
/**
* Set the URI path to be used for the push. The path may start with "/" in which case it is treated as an absolute
* path, otherwise it is relative to the context path of the associated request. There is no path default and
* {@link #path(String)} must be called before every call to {@link #push()}. If a query string is present in the
* argument {@code path}, its contents must be merged with the contents previously passed to {@link #queryString},
* preserving duplicates.
*
* @param path the URI path to be used for the push, which may include a query string.
* @return this builder.
*/
public PushBuilder path(String path);
/**
* Push a resource given the current state of the builder, the method must be non-blocking.
*
* <p>
* Push a resource based on the current state of the PushBuilder. Calling this method does not guarantee the resource
* will actually be pushed, since it is possible the client can decline acceptance of the pushed resource using the
* underlying HTTP/2 protocol.
* </p>
*
* <p>
* If the builder has a session ID, then the pushed request will include the session ID either as a Cookie or as a URI
* parameter as appropriate. The builders query string is merged with any passed query string.
* </p>
*
* <p>
* Before returning from this method, the builder has its path, conditional headers (defined in RFC 7232) nulled. All
* other fields are left as is for possible reuse in another push.
* </p>
*
* @throws IllegalStateException if there was no call to {@link #path} on this instance either between its instantiation
* or the last call to {@code push()} that did not throw an IllegalStateException.
*/
public void push();
/**
* Return the method to be used for the push.
*
* @return the method to be used for the push.
*/
public String getMethod();
/**
* Return the query string to be used for the push.
*
* @return the query string to be used for the push.
*/
public String getQueryString();
/**
* Return the SessionID to be used for the push.
*
* @return the SessionID to be used for the push.
*/
public String getSessionId();
/**
* Return the set of header to be used for the push.
*
* <p>
* The returned set is not backed by the {@code PushBuilder} object, so changes in the returned set are not reflected in
* the {@code PushBuilder} object, and vice-versa.
* </p>
*
* @return the set of header to be used for the push.
*/
public Set<String> getHeaderNames();
/**
* Return the header of the given name to be used for the push.
*
* @param name the name of the header
*
* @return the header of the given name to be used for the push.
*/
public String getHeader(String name);
/**
* Return the URI path to be used for the push.
*
* @return the URI path to be used for the push.
*/
public String getPath();
}