Mercurial Hosting > luan
comparison src/org/eclipse/jetty/server/Response.java @ 813:f8f7cb485c25
remove UserIdentity
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 08 Sep 2016 22:01:33 -0600 |
parents | 09d518d313b7 |
children | 8e9db0bbf4f9 |
comparison
equal
deleted
inserted
replaced
812:700317ba03ad | 813:f8f7cb485c25 |
---|---|
59 * Implements {@link javax.servlet.http.HttpServletResponse} from the <code>javax.servlet.http</code> package. | 59 * Implements {@link javax.servlet.http.HttpServletResponse} from the <code>javax.servlet.http</code> package. |
60 * </p> | 60 * </p> |
61 */ | 61 */ |
62 public class Response implements HttpServletResponse | 62 public class Response implements HttpServletResponse |
63 { | 63 { |
64 private static final Logger LOG = Log.getLogger(Response.class); | 64 private static final Logger LOG = Log.getLogger(Response.class); |
65 | 65 |
66 | 66 |
67 public static final int | 67 public static final int |
68 NONE=0, | 68 NONE=0, |
69 STREAM=1, | 69 STREAM=1, |
70 WRITER=2; | 70 WRITER=2; |
71 | 71 |
72 /** | 72 /** |
73 * If a header name starts with this string, the header (stripped of the prefix) | 73 * If a header name starts with this string, the header (stripped of the prefix) |
74 * can be set during include using only {@link #setHeader(String, String)} or | 74 * can be set during include using only {@link #setHeader(String, String)} or |
75 * {@link #addHeader(String, String)}. | 75 * {@link #addHeader(String, String)}. |
76 */ | 76 */ |
77 public final static String SET_INCLUDE_HEADER_PREFIX = "org.eclipse.jetty.server.include."; | 77 public final static String SET_INCLUDE_HEADER_PREFIX = "org.eclipse.jetty.server.include."; |
78 | 78 |
79 /** | 79 /** |
80 * If this string is found within the comment of a cookie added with {@link #addCookie(Cookie)}, then the cookie | 80 * If this string is found within the comment of a cookie added with {@link #addCookie(Cookie)}, then the cookie |
81 * will be set as HTTP ONLY. | 81 * will be set as HTTP ONLY. |
82 */ | 82 */ |
83 public final static String HTTP_ONLY_COMMENT="__HTTP_ONLY__"; | 83 public final static String HTTP_ONLY_COMMENT="__HTTP_ONLY__"; |
84 | 84 |
85 | 85 |
86 /* ------------------------------------------------------------ */ | 86 /* ------------------------------------------------------------ */ |
87 public static Response getResponse(HttpServletResponse response) | 87 public static Response getResponse(HttpServletResponse response) |
88 { | 88 { |
89 if (response instanceof Response) | 89 if (response instanceof Response) |
90 return (Response)response; | 90 return (Response)response; |
91 | 91 |
92 return AbstractHttpConnection.getCurrentConnection().getResponse(); | 92 return AbstractHttpConnection.getCurrentConnection().getResponse(); |
93 } | 93 } |
94 | 94 |
95 private final AbstractHttpConnection _connection; | 95 private final AbstractHttpConnection _connection; |
96 private int _status=SC_OK; | 96 private int _status=SC_OK; |
97 private String _reason; | 97 private String _reason; |
98 private Locale _locale; | 98 private Locale _locale; |
99 private String _mimeType; | 99 private String _mimeType; |
100 private CachedBuffer _cachedMimeType; | 100 private CachedBuffer _cachedMimeType; |
101 private String _characterEncoding; | 101 private String _characterEncoding; |
102 private boolean _explicitEncoding; | 102 private boolean _explicitEncoding; |
103 private String _contentType; | 103 private String _contentType; |
104 private volatile int _outputState; | 104 private volatile int _outputState; |
105 private PrintWriter _writer; | 105 private PrintWriter _writer; |
106 | 106 |
107 /* ------------------------------------------------------------ */ | 107 /* ------------------------------------------------------------ */ |
108 /** | 108 /** |
109 * | 109 * |
110 */ | 110 */ |
111 public Response(AbstractHttpConnection connection) | 111 public Response(AbstractHttpConnection connection) |
112 { | 112 { |
113 _connection=connection; | 113 _connection=connection; |
114 } | 114 } |
115 | 115 |
116 | 116 |
117 /* ------------------------------------------------------------ */ | 117 /* ------------------------------------------------------------ */ |
118 /* | 118 /* |
119 * @see javax.servlet.ServletResponse#reset() | 119 * @see javax.servlet.ServletResponse#reset() |
120 */ | 120 */ |
121 protected void recycle() | 121 protected void recycle() |
122 { | 122 { |
123 _status=SC_OK; | 123 _status=SC_OK; |
124 _reason=null; | 124 _reason=null; |
125 _locale=null; | 125 _locale=null; |
126 _mimeType=null; | 126 _mimeType=null; |
127 _cachedMimeType=null; | 127 _cachedMimeType=null; |
128 _characterEncoding=null; | 128 _characterEncoding=null; |
129 _explicitEncoding=false; | 129 _explicitEncoding=false; |
130 _contentType=null; | 130 _contentType=null; |
131 _writer=null; | 131 _writer=null; |
132 _outputState=NONE; | 132 _outputState=NONE; |
133 } | 133 } |
134 | 134 |
135 /* ------------------------------------------------------------ */ | 135 /* ------------------------------------------------------------ */ |
136 /* | 136 /* |
137 * @see javax.servlet.http.HttpServletResponse#addCookie(javax.servlet.http.Cookie) | 137 * @see javax.servlet.http.HttpServletResponse#addCookie(javax.servlet.http.Cookie) |
138 */ | 138 */ |
139 public void addCookie(HttpCookie cookie) | 139 public void addCookie(HttpCookie cookie) |
140 { | 140 { |
141 _connection.getResponseFields().addSetCookie(cookie); | 141 _connection.getResponseFields().addSetCookie(cookie); |
142 } | 142 } |
143 | 143 |
144 /* ------------------------------------------------------------ */ | 144 /* ------------------------------------------------------------ */ |
145 /* | 145 /* |
146 * @see javax.servlet.http.HttpServletResponse#addCookie(javax.servlet.http.Cookie) | 146 * @see javax.servlet.http.HttpServletResponse#addCookie(javax.servlet.http.Cookie) |
147 */ | 147 */ |
148 public void addCookie(Cookie cookie) | 148 public void addCookie(Cookie cookie) |
149 { | 149 { |
150 String comment=cookie.getComment(); | 150 String comment=cookie.getComment(); |
151 boolean http_only=false; | 151 boolean http_only=false; |
152 | 152 |
153 if (comment!=null) | 153 if (comment!=null) |
154 { | 154 { |
155 int i=comment.indexOf(HTTP_ONLY_COMMENT); | 155 int i=comment.indexOf(HTTP_ONLY_COMMENT); |
156 if (i>=0) | 156 if (i>=0) |
157 { | 157 { |
158 http_only=true; | 158 http_only=true; |
159 comment=comment.replace(HTTP_ONLY_COMMENT,"").trim(); | 159 comment=comment.replace(HTTP_ONLY_COMMENT,"").trim(); |
160 if (comment.length()==0) | 160 if (comment.length()==0) |
161 comment=null; | 161 comment=null; |
162 } | 162 } |
163 } | 163 } |
164 _connection.getResponseFields().addSetCookie(cookie.getName(), | 164 _connection.getResponseFields().addSetCookie(cookie.getName(), |
165 cookie.getValue(), | 165 cookie.getValue(), |
166 cookie.getDomain(), | 166 cookie.getDomain(), |
167 cookie.getPath(), | 167 cookie.getPath(), |
168 cookie.getMaxAge(), | 168 cookie.getMaxAge(), |
169 comment, | 169 comment, |
170 cookie.getSecure(), | 170 cookie.getSecure(), |
171 http_only || cookie.isHttpOnly(), | 171 http_only || cookie.isHttpOnly(), |
172 cookie.getVersion()); | 172 cookie.getVersion()); |
173 } | 173 } |
174 | 174 |
175 /* ------------------------------------------------------------ */ | 175 /* ------------------------------------------------------------ */ |
176 /* | 176 /* |
177 * @see javax.servlet.http.HttpServletResponse#containsHeader(java.lang.String) | 177 * @see javax.servlet.http.HttpServletResponse#containsHeader(java.lang.String) |
178 */ | 178 */ |
179 public boolean containsHeader(String name) | 179 public boolean containsHeader(String name) |
180 { | 180 { |
181 return _connection.getResponseFields().containsKey(name); | 181 return _connection.getResponseFields().containsKey(name); |
182 } | 182 } |
183 | 183 |
184 /* ------------------------------------------------------------ */ | 184 /* ------------------------------------------------------------ */ |
185 /* | 185 /* |
186 * @see javax.servlet.http.HttpServletResponse#encodeURL(java.lang.String) | 186 * @see javax.servlet.http.HttpServletResponse#encodeURL(java.lang.String) |
187 */ | 187 */ |
188 public String encodeURL(String url) | 188 public String encodeURL(String url) |
189 { | 189 { |
190 throw new UnsupportedOperationException(); | 190 throw new UnsupportedOperationException(); |
191 } | 191 } |
192 | 192 |
193 /* ------------------------------------------------------------ */ | 193 /* ------------------------------------------------------------ */ |
194 /** | 194 /** |
195 * @see javax.servlet.http.HttpServletResponse#encodeRedirectURL(java.lang.String) | 195 * @see javax.servlet.http.HttpServletResponse#encodeRedirectURL(java.lang.String) |
196 */ | 196 */ |
197 public String encodeRedirectURL(String url) | 197 public String encodeRedirectURL(String url) |
198 { | 198 { |
199 return encodeURL(url); | 199 return encodeURL(url); |
200 } | 200 } |
201 | 201 |
202 /* ------------------------------------------------------------ */ | 202 /* ------------------------------------------------------------ */ |
203 @Deprecated | 203 @Deprecated |
204 public String encodeUrl(String url) | 204 public String encodeUrl(String url) |
205 { | 205 { |
206 return encodeURL(url); | 206 return encodeURL(url); |
207 } | 207 } |
208 | 208 |
209 /* ------------------------------------------------------------ */ | 209 /* ------------------------------------------------------------ */ |
210 @Deprecated | 210 @Deprecated |
211 public String encodeRedirectUrl(String url) | 211 public String encodeRedirectUrl(String url) |
212 { | 212 { |
213 return encodeRedirectURL(url); | 213 return encodeRedirectURL(url); |
214 } | 214 } |
215 | 215 |
216 /* ------------------------------------------------------------ */ | 216 /* ------------------------------------------------------------ */ |
217 /* | 217 /* |
218 * @see javax.servlet.http.HttpServletResponse#sendError(int, java.lang.String) | 218 * @see javax.servlet.http.HttpServletResponse#sendError(int, java.lang.String) |
219 */ | 219 */ |
220 public void sendError(int code, String message) throws IOException | 220 public void sendError(int code, String message) throws IOException |
221 { | 221 { |
222 if (_connection.isIncluding()) | 222 if (_connection.isIncluding()) |
223 return; | 223 return; |
224 | 224 |
225 if (isCommitted()) | 225 if (isCommitted()) |
226 LOG.warn("Committed before "+code+" "+message); | 226 LOG.warn("Committed before "+code+" "+message); |
227 | 227 |
228 resetBuffer(); | 228 resetBuffer(); |
229 _characterEncoding=null; | 229 _characterEncoding=null; |
230 setHeader(HttpHeaders.EXPIRES,null); | 230 setHeader(HttpHeaders.EXPIRES,null); |
231 setHeader(HttpHeaders.LAST_MODIFIED,null); | 231 setHeader(HttpHeaders.LAST_MODIFIED,null); |
232 setHeader(HttpHeaders.CACHE_CONTROL,null); | 232 setHeader(HttpHeaders.CACHE_CONTROL,null); |
233 setHeader(HttpHeaders.CONTENT_TYPE,null); | 233 setHeader(HttpHeaders.CONTENT_TYPE,null); |
234 setHeader(HttpHeaders.CONTENT_LENGTH,null); | 234 setHeader(HttpHeaders.CONTENT_LENGTH,null); |
235 | 235 |
236 _outputState=NONE; | 236 _outputState=NONE; |
237 setStatus(code,message); | 237 setStatus(code,message); |
238 | 238 |
239 if (message==null) | 239 if (message==null) |
240 message=HttpStatus.getMessage(code); | 240 message=HttpStatus.getMessage(code); |
241 | 241 |
242 // If we are allowed to have a body | 242 // If we are allowed to have a body |
243 if (code!=SC_NO_CONTENT && | 243 if (code!=SC_NO_CONTENT && |
244 code!=SC_NOT_MODIFIED && | 244 code!=SC_NOT_MODIFIED && |
245 code!=SC_PARTIAL_CONTENT && | 245 code!=SC_PARTIAL_CONTENT && |
246 code>=SC_OK) | 246 code>=SC_OK) |
247 { | 247 { |
248 Request request = _connection.getRequest(); | 248 Request request = _connection.getRequest(); |
249 | 249 |
250 ErrorHandler error_handler = null; | 250 ErrorHandler error_handler = null; |
251 ContextHandler.Context context = request.getContext(); | 251 ContextHandler.Context context = request.getContext(); |
252 if (context!=null) | 252 if (context!=null) |
253 error_handler=context.getContextHandler().getErrorHandler(); | 253 error_handler=context.getContextHandler().getErrorHandler(); |
254 if (error_handler==null) | 254 if (error_handler==null) |
255 error_handler = _connection.getConnector().getServer().getBean(ErrorHandler.class); | 255 error_handler = _connection.getConnector().getServer().getBean(ErrorHandler.class); |
256 if (error_handler!=null) | 256 if (error_handler!=null) |
257 { | 257 { |
258 request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,new Integer(code)); | 258 request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,new Integer(code)); |
259 request.setAttribute(RequestDispatcher.ERROR_MESSAGE, message); | 259 request.setAttribute(RequestDispatcher.ERROR_MESSAGE, message); |
260 request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI, request.getRequestURI()); | 260 request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI, request.getRequestURI()); |
261 request.setAttribute(RequestDispatcher.ERROR_SERVLET_NAME,request.getServletName()); | 261 error_handler.handle(null,_connection.getRequest(),_connection.getRequest(),this ); |
262 error_handler.handle(null,_connection.getRequest(),_connection.getRequest(),this ); | 262 } |
263 } | 263 else |
264 else | 264 { |
265 { | 265 setHeader(HttpHeaders.CACHE_CONTROL, "must-revalidate,no-cache,no-store"); |
266 setHeader(HttpHeaders.CACHE_CONTROL, "must-revalidate,no-cache,no-store"); | 266 setContentType(MimeTypes.TEXT_HTML_8859_1); |
267 setContentType(MimeTypes.TEXT_HTML_8859_1); | 267 ByteArrayISO8859Writer writer= new ByteArrayISO8859Writer(2048); |
268 ByteArrayISO8859Writer writer= new ByteArrayISO8859Writer(2048); | 268 if (message != null) |
269 if (message != null) | 269 { |
270 { | 270 message= StringUtil.replace(message, "&", "&"); |
271 message= StringUtil.replace(message, "&", "&"); | 271 message= StringUtil.replace(message, "<", "<"); |
272 message= StringUtil.replace(message, "<", "<"); | 272 message= StringUtil.replace(message, ">", ">"); |
273 message= StringUtil.replace(message, ">", ">"); | 273 } |
274 } | 274 String uri= request.getRequestURI(); |
275 String uri= request.getRequestURI(); | 275 if (uri!=null) |
276 if (uri!=null) | 276 { |
277 { | 277 uri= StringUtil.replace(uri, "&", "&"); |
278 uri= StringUtil.replace(uri, "&", "&"); | 278 uri= StringUtil.replace(uri, "<", "<"); |
279 uri= StringUtil.replace(uri, "<", "<"); | 279 uri= StringUtil.replace(uri, ">", ">"); |
280 uri= StringUtil.replace(uri, ">", ">"); | 280 } |
281 } | 281 |
282 | 282 writer.write("<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=ISO-8859-1\"/>\n"); |
283 writer.write("<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=ISO-8859-1\"/>\n"); | 283 writer.write("<title>Error "); |
284 writer.write("<title>Error "); | 284 writer.write(Integer.toString(code)); |
285 writer.write(Integer.toString(code)); | 285 writer.write(' '); |
286 writer.write(' '); | 286 if (message==null) |
287 if (message==null) | 287 message=HttpStatus.getMessage(code); |
288 message=HttpStatus.getMessage(code); | 288 writer.write(message); |
289 writer.write(message); | 289 writer.write("</title>\n</head>\n<body>\n<h2>HTTP ERROR: "); |
290 writer.write("</title>\n</head>\n<body>\n<h2>HTTP ERROR: "); | 290 writer.write(Integer.toString(code)); |
291 writer.write(Integer.toString(code)); | 291 writer.write("</h2>\n<p>Problem accessing "); |
292 writer.write("</h2>\n<p>Problem accessing "); | 292 writer.write(uri); |
293 writer.write(uri); | 293 writer.write(". Reason:\n<pre> "); |
294 writer.write(". Reason:\n<pre> "); | 294 writer.write(message); |
295 writer.write(message); | 295 writer.write("</pre>"); |
296 writer.write("</pre>"); | 296 writer.write("</p>\n<hr /><i><small>Powered by Jetty://</small></i>"); |
297 writer.write("</p>\n<hr /><i><small>Powered by Jetty://</small></i>"); | 297 |
298 | 298 for (int i= 0; i < 20; i++) |
299 for (int i= 0; i < 20; i++) | 299 writer.write("\n "); |
300 writer.write("\n "); | 300 writer.write("\n</body>\n</html>\n"); |
301 writer.write("\n</body>\n</html>\n"); | 301 |
302 | 302 writer.flush(); |
303 writer.flush(); | 303 setContentLength(writer.size()); |
304 setContentLength(writer.size()); | 304 writer.writeTo(getOutputStream()); |
305 writer.writeTo(getOutputStream()); | 305 writer.destroy(); |
306 writer.destroy(); | 306 } |
307 } | 307 } |
308 } | 308 else if (code!=SC_PARTIAL_CONTENT) |
309 else if (code!=SC_PARTIAL_CONTENT) | 309 { |
310 { | 310 _connection.getRequestFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER); |
311 _connection.getRequestFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER); | 311 _connection.getRequestFields().remove(HttpHeaders.CONTENT_LENGTH_BUFFER); |
312 _connection.getRequestFields().remove(HttpHeaders.CONTENT_LENGTH_BUFFER); | 312 _characterEncoding=null; |
313 _characterEncoding=null; | 313 _mimeType=null; |
314 _mimeType=null; | 314 _cachedMimeType=null; |
315 _cachedMimeType=null; | 315 } |
316 } | 316 |
317 | 317 complete(); |
318 complete(); | 318 } |
319 } | 319 |
320 | 320 /* ------------------------------------------------------------ */ |
321 /* ------------------------------------------------------------ */ | 321 /* |
322 /* | 322 * @see javax.servlet.http.HttpServletResponse#sendError(int) |
323 * @see javax.servlet.http.HttpServletResponse#sendError(int) | 323 */ |
324 */ | 324 public void sendError(int sc) throws IOException |
325 public void sendError(int sc) throws IOException | 325 { |
326 { | 326 if (sc==102) |
327 if (sc==102) | 327 sendProcessing(); |
328 sendProcessing(); | 328 else |
329 else | 329 sendError(sc,null); |
330 sendError(sc,null); | 330 } |
331 } | 331 |
332 | 332 /* ------------------------------------------------------------ */ |
333 /* ------------------------------------------------------------ */ | 333 /* Send a 102-Processing response. |
334 /* Send a 102-Processing response. | 334 * If the connection is a HTTP connection, the version is 1.1 and the |
335 * If the connection is a HTTP connection, the version is 1.1 and the | 335 * request has a Expect header starting with 102, then a 102 response is |
336 * request has a Expect header starting with 102, then a 102 response is | 336 * sent. This indicates that the request still be processed and real response |
337 * sent. This indicates that the request still be processed and real response | 337 * can still be sent. This method is called by sendError if it is passed 102. |
338 * can still be sent. This method is called by sendError if it is passed 102. | 338 * @see javax.servlet.http.HttpServletResponse#sendError(int) |
339 * @see javax.servlet.http.HttpServletResponse#sendError(int) | 339 */ |
340 */ | 340 public void sendProcessing() throws IOException |
341 public void sendProcessing() throws IOException | 341 { |
342 { | 342 if (_connection.isExpecting102Processing() && !isCommitted()) |
343 if (_connection.isExpecting102Processing() && !isCommitted()) | 343 ((HttpGenerator)_connection.getGenerator()).send1xx(HttpStatus.PROCESSING_102); |
344 ((HttpGenerator)_connection.getGenerator()).send1xx(HttpStatus.PROCESSING_102); | 344 } |
345 } | 345 |
346 | 346 /* ------------------------------------------------------------ */ |
347 /* ------------------------------------------------------------ */ | 347 /* |
348 /* | 348 * @see javax.servlet.http.HttpServletResponse#sendRedirect(java.lang.String) |
349 * @see javax.servlet.http.HttpServletResponse#sendRedirect(java.lang.String) | 349 */ |
350 */ | 350 public void sendRedirect(String location) throws IOException |
351 public void sendRedirect(String location) throws IOException | 351 { |
352 { | 352 if (_connection.isIncluding()) |
353 if (_connection.isIncluding()) | 353 return; |
354 return; | 354 |
355 | 355 if (location==null) |
356 if (location==null) | 356 throw new IllegalArgumentException(); |
357 throw new IllegalArgumentException(); | 357 |
358 | 358 if (!URIUtil.hasScheme(location)) |
359 if (!URIUtil.hasScheme(location)) | 359 { |
360 { | 360 StringBuilder buf = _connection.getRequest().getRootURL(); |
361 StringBuilder buf = _connection.getRequest().getRootURL(); | 361 if (location.startsWith("/")) |
362 if (location.startsWith("/")) | 362 buf.append(location); |
363 buf.append(location); | 363 else |
364 else | 364 { |
365 { | 365 String path=_connection.getRequest().getRequestURI(); |
366 String path=_connection.getRequest().getRequestURI(); | 366 String parent=(path.endsWith("/"))?path:URIUtil.parentPath(path); |
367 String parent=(path.endsWith("/"))?path:URIUtil.parentPath(path); | 367 location=URIUtil.addPaths(parent,location); |
368 location=URIUtil.addPaths(parent,location); | 368 if(location==null) |
369 if(location==null) | 369 throw new IllegalStateException("path cannot be above root"); |
370 throw new IllegalStateException("path cannot be above root"); | 370 if (!location.startsWith("/")) |
371 if (!location.startsWith("/")) | 371 buf.append('/'); |
372 buf.append('/'); | 372 buf.append(location); |
373 buf.append(location); | 373 } |
374 } | 374 |
375 | 375 location=buf.toString(); |
376 location=buf.toString(); | 376 HttpURI uri = new HttpURI(location); |
377 HttpURI uri = new HttpURI(location); | 377 String path=uri.getDecodedPath(); |
378 String path=uri.getDecodedPath(); | 378 String canonical=URIUtil.canonicalPath(path); |
379 String canonical=URIUtil.canonicalPath(path); | 379 if (canonical==null) |
380 if (canonical==null) | 380 throw new IllegalArgumentException(); |
381 throw new IllegalArgumentException(); | 381 if (!canonical.equals(path)) |
382 if (!canonical.equals(path)) | 382 { |
383 { | 383 buf = _connection.getRequest().getRootURL(); |
384 buf = _connection.getRequest().getRootURL(); | 384 buf.append(URIUtil.encodePath(canonical)); |
385 buf.append(URIUtil.encodePath(canonical)); | 385 String param=uri.getParam(); |
386 String param=uri.getParam(); | 386 if (param!=null) |
387 if (param!=null) | 387 { |
388 { | 388 buf.append(';'); |
389 buf.append(';'); | 389 buf.append(param); |
390 buf.append(param); | 390 } |
391 } | 391 String query=uri.getQuery(); |
392 String query=uri.getQuery(); | 392 if (query!=null) |
393 if (query!=null) | 393 { |
394 { | 394 buf.append('?'); |
395 buf.append('?'); | 395 buf.append(query); |
396 buf.append(query); | 396 } |
397 } | 397 String fragment=uri.getFragment(); |
398 String fragment=uri.getFragment(); | 398 if (fragment!=null) |
399 if (fragment!=null) | 399 { |
400 { | 400 buf.append('#'); |
401 buf.append('#'); | 401 buf.append(fragment); |
402 buf.append(fragment); | 402 } |
403 } | 403 location=buf.toString(); |
404 location=buf.toString(); | 404 } |
405 } | 405 } |
406 } | 406 |
407 | 407 resetBuffer(); |
408 resetBuffer(); | 408 setHeader(HttpHeaders.LOCATION,location); |
409 setHeader(HttpHeaders.LOCATION,location); | 409 setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); |
410 setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); | 410 complete(); |
411 complete(); | 411 |
412 | 412 } |
413 } | 413 |
414 | 414 /* ------------------------------------------------------------ */ |
415 /* ------------------------------------------------------------ */ | 415 /* |
416 /* | 416 * @see javax.servlet.http.HttpServletResponse#setDateHeader(java.lang.String, long) |
417 * @see javax.servlet.http.HttpServletResponse#setDateHeader(java.lang.String, long) | 417 */ |
418 */ | 418 public void setDateHeader(String name, long date) |
419 public void setDateHeader(String name, long date) | 419 { |
420 { | 420 if (!_connection.isIncluding()) |
421 if (!_connection.isIncluding()) | 421 _connection.getResponseFields().putDateField(name, date); |
422 _connection.getResponseFields().putDateField(name, date); | 422 } |
423 } | 423 |
424 | 424 /* ------------------------------------------------------------ */ |
425 /* ------------------------------------------------------------ */ | 425 /* |
426 /* | 426 * @see javax.servlet.http.HttpServletResponse#addDateHeader(java.lang.String, long) |
427 * @see javax.servlet.http.HttpServletResponse#addDateHeader(java.lang.String, long) | 427 */ |
428 */ | 428 public void addDateHeader(String name, long date) |
429 public void addDateHeader(String name, long date) | 429 { |
430 { | 430 if (!_connection.isIncluding()) |
431 if (!_connection.isIncluding()) | 431 _connection.getResponseFields().addDateField(name, date); |
432 _connection.getResponseFields().addDateField(name, date); | 432 } |
433 } | 433 |
434 | 434 /* ------------------------------------------------------------ */ |
435 /* ------------------------------------------------------------ */ | 435 /* |
436 /* | 436 * @see javax.servlet.http.HttpServletResponse#setHeader(java.lang.String, java.lang.String) |
437 * @see javax.servlet.http.HttpServletResponse#setHeader(java.lang.String, java.lang.String) | 437 */ |
438 */ | 438 public void setHeader(String name, String value) |
439 public void setHeader(String name, String value) | 439 { |
440 { | 440 if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name)) |
441 if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name)) | 441 setContentType(value); |
442 setContentType(value); | 442 else |
443 else | 443 { |
444 { | 444 if (_connection.isIncluding()) |
445 if (_connection.isIncluding()) | 445 { |
446 { | 446 if (name.startsWith(SET_INCLUDE_HEADER_PREFIX)) |
447 if (name.startsWith(SET_INCLUDE_HEADER_PREFIX)) | 447 name=name.substring(SET_INCLUDE_HEADER_PREFIX.length()); |
448 name=name.substring(SET_INCLUDE_HEADER_PREFIX.length()); | 448 else |
449 else | 449 return; |
450 return; | 450 } |
451 } | 451 _connection.getResponseFields().put(name, value); |
452 _connection.getResponseFields().put(name, value); | 452 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) |
453 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) | 453 { |
454 { | 454 if (value==null) |
455 if (value==null) | 455 _connection._generator.setContentLength(-1); |
456 _connection._generator.setContentLength(-1); | 456 else |
457 else | 457 _connection._generator.setContentLength(Long.parseLong(value)); |
458 _connection._generator.setContentLength(Long.parseLong(value)); | 458 } |
459 } | 459 } |
460 } | 460 } |
461 } | 461 |
462 | 462 |
463 | 463 /* ------------------------------------------------------------ */ |
464 /* ------------------------------------------------------------ */ | 464 public Collection<String> getHeaderNames() |
465 public Collection<String> getHeaderNames() | 465 { |
466 { | 466 final HttpFields fields=_connection.getResponseFields(); |
467 final HttpFields fields=_connection.getResponseFields(); | 467 return fields.getFieldNamesCollection(); |
468 return fields.getFieldNamesCollection(); | 468 } |
469 } | 469 |
470 | 470 /* ------------------------------------------------------------ */ |
471 /* ------------------------------------------------------------ */ | 471 /* |
472 /* | 472 */ |
473 */ | 473 public String getHeader(String name) |
474 public String getHeader(String name) | 474 { |
475 { | 475 return _connection.getResponseFields().getStringField(name); |
476 return _connection.getResponseFields().getStringField(name); | 476 } |
477 } | 477 |
478 | 478 /* ------------------------------------------------------------ */ |
479 /* ------------------------------------------------------------ */ | 479 /* |
480 /* | 480 */ |
481 */ | 481 public Collection<String> getHeaders(String name) |
482 public Collection<String> getHeaders(String name) | 482 { |
483 { | 483 final HttpFields fields=_connection.getResponseFields(); |
484 final HttpFields fields=_connection.getResponseFields(); | 484 Collection<String> i = fields.getValuesCollection(name); |
485 Collection<String> i = fields.getValuesCollection(name); | 485 if (i==null) |
486 if (i==null) | 486 return Collections.EMPTY_LIST; |
487 return Collections.EMPTY_LIST; | 487 return i; |
488 return i; | 488 } |
489 } | 489 |
490 | 490 /* ------------------------------------------------------------ */ |
491 /* ------------------------------------------------------------ */ | 491 /* |
492 /* | 492 * @see javax.servlet.http.HttpServletResponse#addHeader(java.lang.String, java.lang.String) |
493 * @see javax.servlet.http.HttpServletResponse#addHeader(java.lang.String, java.lang.String) | 493 */ |
494 */ | 494 public void addHeader(String name, String value) |
495 public void addHeader(String name, String value) | 495 { |
496 { | 496 |
497 | 497 if (_connection.isIncluding()) |
498 if (_connection.isIncluding()) | 498 { |
499 { | 499 if (name.startsWith(SET_INCLUDE_HEADER_PREFIX)) |
500 if (name.startsWith(SET_INCLUDE_HEADER_PREFIX)) | 500 name=name.substring(SET_INCLUDE_HEADER_PREFIX.length()); |
501 name=name.substring(SET_INCLUDE_HEADER_PREFIX.length()); | 501 else |
502 else | 502 return; |
503 return; | 503 } |
504 } | 504 |
505 | 505 if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name)) |
506 if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name)) | 506 { |
507 { | 507 setContentType(value); |
508 setContentType(value); | 508 return; |
509 return; | 509 } |
510 } | 510 |
511 | 511 _connection.getResponseFields().add(name, value); |
512 _connection.getResponseFields().add(name, value); | 512 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) |
513 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) | 513 _connection._generator.setContentLength(Long.parseLong(value)); |
514 _connection._generator.setContentLength(Long.parseLong(value)); | 514 } |
515 } | 515 |
516 | 516 /* ------------------------------------------------------------ */ |
517 /* ------------------------------------------------------------ */ | 517 /* |
518 /* | 518 * @see javax.servlet.http.HttpServletResponse#setIntHeader(java.lang.String, int) |
519 * @see javax.servlet.http.HttpServletResponse#setIntHeader(java.lang.String, int) | 519 */ |
520 */ | 520 public void setIntHeader(String name, int value) |
521 public void setIntHeader(String name, int value) | 521 { |
522 { | 522 if (!_connection.isIncluding()) |
523 if (!_connection.isIncluding()) | 523 { |
524 { | 524 _connection.getResponseFields().putLongField(name, value); |
525 _connection.getResponseFields().putLongField(name, value); | 525 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) |
526 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) | 526 _connection._generator.setContentLength(value); |
527 _connection._generator.setContentLength(value); | 527 } |
528 } | 528 } |
529 } | 529 |
530 | 530 /* ------------------------------------------------------------ */ |
531 /* ------------------------------------------------------------ */ | 531 /* |
532 /* | 532 * @see javax.servlet.http.HttpServletResponse#addIntHeader(java.lang.String, int) |
533 * @see javax.servlet.http.HttpServletResponse#addIntHeader(java.lang.String, int) | 533 */ |
534 */ | 534 public void addIntHeader(String name, int value) |
535 public void addIntHeader(String name, int value) | 535 { |
536 { | 536 if (!_connection.isIncluding()) |
537 if (!_connection.isIncluding()) | 537 { |
538 { | 538 _connection.getResponseFields().addLongField(name, value); |
539 _connection.getResponseFields().addLongField(name, value); | 539 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) |
540 if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) | 540 _connection._generator.setContentLength(value); |
541 _connection._generator.setContentLength(value); | 541 } |
542 } | 542 } |
543 } | 543 |
544 | 544 /* ------------------------------------------------------------ */ |
545 /* ------------------------------------------------------------ */ | 545 /* |
546 /* | 546 * @see javax.servlet.http.HttpServletResponse#setStatus(int) |
547 * @see javax.servlet.http.HttpServletResponse#setStatus(int) | 547 */ |
548 */ | 548 public void setStatus(int sc) |
549 public void setStatus(int sc) | 549 { |
550 { | 550 setStatus(sc,null); |
551 setStatus(sc,null); | 551 } |
552 } | 552 |
553 | 553 /* ------------------------------------------------------------ */ |
554 /* ------------------------------------------------------------ */ | 554 /* |
555 /* | 555 * @see javax.servlet.http.HttpServletResponse#setStatus(int, java.lang.String) |
556 * @see javax.servlet.http.HttpServletResponse#setStatus(int, java.lang.String) | 556 */ |
557 */ | 557 public void setStatus(int sc, String sm) |
558 public void setStatus(int sc, String sm) | 558 { |
559 { | 559 if (sc<=0) |
560 if (sc<=0) | 560 throw new IllegalArgumentException(); |
561 throw new IllegalArgumentException(); | 561 if (!_connection.isIncluding()) |
562 if (!_connection.isIncluding()) | 562 { |
563 { | 563 _status=sc; |
564 _status=sc; | 564 _reason=sm; |
565 _reason=sm; | 565 } |
566 } | 566 } |
567 } | 567 |
568 | 568 /* ------------------------------------------------------------ */ |
569 /* ------------------------------------------------------------ */ | 569 /* |
570 /* | 570 * @see javax.servlet.ServletResponse#getCharacterEncoding() |
571 * @see javax.servlet.ServletResponse#getCharacterEncoding() | 571 */ |
572 */ | 572 public String getCharacterEncoding() |
573 public String getCharacterEncoding() | 573 { |
574 { | 574 if (_characterEncoding==null) |
575 if (_characterEncoding==null) | 575 _characterEncoding=StringUtil.__ISO_8859_1; |
576 _characterEncoding=StringUtil.__ISO_8859_1; | 576 return _characterEncoding; |
577 return _characterEncoding; | 577 } |
578 } | 578 |
579 | 579 /* ------------------------------------------------------------ */ |
580 /* ------------------------------------------------------------ */ | 580 String getSetCharacterEncoding() |
581 String getSetCharacterEncoding() | 581 { |
582 { | 582 return _characterEncoding; |
583 return _characterEncoding; | 583 } |
584 } | 584 |
585 | 585 /* ------------------------------------------------------------ */ |
586 /* ------------------------------------------------------------ */ | 586 /* |
587 /* | 587 * @see javax.servlet.ServletResponse#getContentType() |
588 * @see javax.servlet.ServletResponse#getContentType() | 588 */ |
589 */ | 589 public String getContentType() |
590 public String getContentType() | 590 { |
591 { | 591 return _contentType; |
592 return _contentType; | 592 } |
593 } | 593 |
594 | 594 /* ------------------------------------------------------------ */ |
595 /* ------------------------------------------------------------ */ | 595 /* |
596 /* | 596 * @see javax.servlet.ServletResponse#getOutputStream() |
597 * @see javax.servlet.ServletResponse#getOutputStream() | 597 */ |
598 */ | 598 public ServletOutputStream getOutputStream() throws IOException |
599 public ServletOutputStream getOutputStream() throws IOException | 599 { |
600 { | 600 if (_outputState!=NONE && _outputState!=STREAM) |
601 if (_outputState!=NONE && _outputState!=STREAM) | 601 throw new IllegalStateException("WRITER"); |
602 throw new IllegalStateException("WRITER"); | 602 |
603 | 603 ServletOutputStream out = _connection.getOutputStream(); |
604 ServletOutputStream out = _connection.getOutputStream(); | 604 _outputState=STREAM; |
605 _outputState=STREAM; | 605 return out; |
606 return out; | 606 } |
607 } | 607 |
608 | 608 /* ------------------------------------------------------------ */ |
609 /* ------------------------------------------------------------ */ | 609 public boolean isWriting() |
610 public boolean isWriting() | 610 { |
611 { | 611 return _outputState==WRITER; |
612 return _outputState==WRITER; | 612 } |
613 } | 613 |
614 | 614 /* ------------------------------------------------------------ */ |
615 /* ------------------------------------------------------------ */ | 615 public boolean isOutputing() |
616 public boolean isOutputing() | 616 { |
617 { | 617 return _outputState!=NONE; |
618 return _outputState!=NONE; | 618 } |
619 } | 619 |
620 | 620 /* ------------------------------------------------------------ */ |
621 /* ------------------------------------------------------------ */ | 621 /* |
622 /* | 622 * @see javax.servlet.ServletResponse#getWriter() |
623 * @see javax.servlet.ServletResponse#getWriter() | 623 */ |
624 */ | 624 public PrintWriter getWriter() throws IOException |
625 public PrintWriter getWriter() throws IOException | 625 { |
626 { | 626 if (_outputState!=NONE && _outputState!=WRITER) |
627 if (_outputState!=NONE && _outputState!=WRITER) | 627 throw new IllegalStateException("STREAM"); |
628 throw new IllegalStateException("STREAM"); | 628 |
629 | 629 /* if there is no writer yet */ |
630 /* if there is no writer yet */ | 630 if (_writer==null) |
631 if (_writer==null) | 631 { |
632 { | 632 /* get encoding from Content-Type header */ |
633 /* get encoding from Content-Type header */ | 633 String encoding = _characterEncoding; |
634 String encoding = _characterEncoding; | 634 |
635 | 635 if (encoding==null) |
636 if (encoding==null) | 636 { |
637 { | 637 /* implementation of educated defaults */ |
638 /* implementation of educated defaults */ | 638 if(_cachedMimeType != null) |
639 if(_cachedMimeType != null) | 639 encoding = MimeTypes.getCharsetFromContentType(_cachedMimeType); |
640 encoding = MimeTypes.getCharsetFromContentType(_cachedMimeType); | 640 |
641 | 641 if (encoding==null) |
642 if (encoding==null) | 642 encoding = StringUtil.__ISO_8859_1; |
643 encoding = StringUtil.__ISO_8859_1; | 643 |
644 | 644 setCharacterEncoding(encoding); |
645 setCharacterEncoding(encoding); | 645 } |
646 } | 646 |
647 | 647 /* construct Writer using correct encoding */ |
648 /* construct Writer using correct encoding */ | 648 _writer = _connection.getPrintWriter(encoding); |
649 _writer = _connection.getPrintWriter(encoding); | 649 } |
650 } | 650 _outputState=WRITER; |
651 _outputState=WRITER; | 651 return _writer; |
652 return _writer; | 652 } |
653 } | 653 |
654 | 654 /* ------------------------------------------------------------ */ |
655 /* ------------------------------------------------------------ */ | 655 /* |
656 /* | 656 * @see javax.servlet.ServletResponse#setCharacterEncoding(java.lang.String) |
657 * @see javax.servlet.ServletResponse#setCharacterEncoding(java.lang.String) | 657 */ |
658 */ | 658 public void setCharacterEncoding(String encoding) |
659 public void setCharacterEncoding(String encoding) | 659 { |
660 { | 660 if (_connection.isIncluding()) |
661 if (_connection.isIncluding()) | 661 return; |
662 return; | 662 |
663 | 663 if (this._outputState==0 && !isCommitted()) |
664 if (this._outputState==0 && !isCommitted()) | 664 { |
665 { | 665 _explicitEncoding=true; |
666 _explicitEncoding=true; | 666 |
667 | 667 if (encoding==null) |
668 if (encoding==null) | 668 { |
669 { | 669 // Clear any encoding. |
670 // Clear any encoding. | 670 if (_characterEncoding!=null) |
671 if (_characterEncoding!=null) | 671 { |
672 { | 672 _characterEncoding=null; |
673 _characterEncoding=null; | 673 if (_cachedMimeType!=null) |
674 if (_cachedMimeType!=null) | 674 _contentType=_cachedMimeType.toString(); |
675 _contentType=_cachedMimeType.toString(); | 675 else if (_mimeType!=null) |
676 else if (_mimeType!=null) | 676 _contentType=_mimeType; |
677 _contentType=_mimeType; | 677 else |
678 else | 678 _contentType=null; |
679 _contentType=null; | 679 |
680 | 680 if (_contentType==null) |
681 if (_contentType==null) | 681 _connection.getResponseFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER); |
682 _connection.getResponseFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER); | 682 else |
683 else | 683 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
684 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 684 } |
685 } | 685 } |
686 } | 686 else |
687 else | 687 { |
688 { | 688 // No, so just add this one to the mimetype |
689 // No, so just add this one to the mimetype | 689 _characterEncoding=encoding; |
690 _characterEncoding=encoding; | 690 if (_contentType!=null) |
691 if (_contentType!=null) | 691 { |
692 { | 692 int i0=_contentType.indexOf(';'); |
693 int i0=_contentType.indexOf(';'); | 693 if (i0<0) |
694 if (i0<0) | 694 { |
695 { | 695 _contentType=null; |
696 _contentType=null; | 696 if(_cachedMimeType!=null) |
697 if(_cachedMimeType!=null) | 697 { |
698 { | 698 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding); |
699 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding); | 699 if (content_type!=null) |
700 if (content_type!=null) | 700 { |
701 { | 701 _contentType=content_type.toString(); |
702 _contentType=content_type.toString(); | 702 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type); |
703 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type); | 703 } |
704 } | 704 } |
705 } | 705 |
706 | 706 if (_contentType==null) |
707 if (_contentType==null) | 707 { |
708 { | 708 _contentType = _mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); |
709 _contentType = _mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); | 709 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
710 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 710 } |
711 } | 711 } |
712 } | 712 else |
713 else | 713 { |
714 { | 714 int i1=_contentType.indexOf("charset=",i0); |
715 int i1=_contentType.indexOf("charset=",i0); | 715 if (i1<0) |
716 if (i1<0) | 716 { |
717 { | 717 _contentType = _contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); |
718 _contentType = _contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); | 718 } |
719 } | 719 else |
720 else | 720 { |
721 { | 721 int i8=i1+8; |
722 int i8=i1+8; | 722 int i2=_contentType.indexOf(" ",i8); |
723 int i2=_contentType.indexOf(" ",i8); | 723 if (i2<0) |
724 if (i2<0) | 724 _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); |
725 _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); | 725 else |
726 else | 726 _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ")+_contentType.substring(i2); |
727 _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ")+_contentType.substring(i2); | 727 } |
728 } | 728 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
729 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 729 } |
730 } | 730 } |
731 } | 731 } |
732 } | 732 } |
733 } | 733 } |
734 } | 734 |
735 | 735 /* ------------------------------------------------------------ */ |
736 /* ------------------------------------------------------------ */ | 736 /* |
737 /* | 737 * @see javax.servlet.ServletResponse#setContentLength(int) |
738 * @see javax.servlet.ServletResponse#setContentLength(int) | 738 */ |
739 */ | 739 public void setContentLength(int len) |
740 public void setContentLength(int len) | 740 { |
741 { | 741 // Protect from setting after committed as default handling |
742 // Protect from setting after committed as default handling | 742 // of a servlet HEAD request ALWAYS sets _content length, even |
743 // of a servlet HEAD request ALWAYS sets _content length, even | 743 // if the getHandling committed the response! |
744 // if the getHandling committed the response! | 744 if (isCommitted() || _connection.isIncluding()) |
745 if (isCommitted() || _connection.isIncluding()) | 745 return; |
746 return; | 746 _connection._generator.setContentLength(len); |
747 _connection._generator.setContentLength(len); | 747 if (len>0) |
748 if (len>0) | 748 { |
749 { | 749 _connection.getResponseFields().putLongField(HttpHeaders.CONTENT_LENGTH, len); |
750 _connection.getResponseFields().putLongField(HttpHeaders.CONTENT_LENGTH, len); | 750 if (_connection._generator.isAllContentWritten()) |
751 if (_connection._generator.isAllContentWritten()) | 751 { |
752 { | 752 if (_outputState==WRITER) |
753 if (_outputState==WRITER) | 753 _writer.close(); |
754 _writer.close(); | 754 else if (_outputState==STREAM) |
755 else if (_outputState==STREAM) | 755 { |
756 { | 756 try |
757 try | 757 { |
758 { | 758 getOutputStream().close(); |
759 getOutputStream().close(); | 759 } |
760 } | 760 catch(IOException e) |
761 catch(IOException e) | 761 { |
762 { | 762 throw new RuntimeException(e); |
763 throw new RuntimeException(e); | 763 } |
764 } | 764 } |
765 } | 765 } |
766 } | 766 } |
767 } | 767 } |
768 } | 768 |
769 | 769 /* ------------------------------------------------------------ */ |
770 /* ------------------------------------------------------------ */ | 770 /* |
771 /* | 771 * @see javax.servlet.ServletResponse#setContentLength(int) |
772 * @see javax.servlet.ServletResponse#setContentLength(int) | 772 */ |
773 */ | 773 public void setLongContentLength(long len) |
774 public void setLongContentLength(long len) | 774 { |
775 { | 775 // Protect from setting after committed as default handling |
776 // Protect from setting after committed as default handling | 776 // of a servlet HEAD request ALWAYS sets _content length, even |
777 // of a servlet HEAD request ALWAYS sets _content length, even | 777 // if the getHandling committed the response! |
778 // if the getHandling committed the response! | 778 if (isCommitted() || _connection.isIncluding()) |
779 if (isCommitted() || _connection.isIncluding()) | 779 return; |
780 return; | 780 _connection._generator.setContentLength(len); |
781 _connection._generator.setContentLength(len); | 781 _connection.getResponseFields().putLongField(HttpHeaders.CONTENT_LENGTH, len); |
782 _connection.getResponseFields().putLongField(HttpHeaders.CONTENT_LENGTH, len); | 782 } |
783 } | 783 |
784 | 784 /* ------------------------------------------------------------ */ |
785 /* ------------------------------------------------------------ */ | 785 /* |
786 /* | 786 * @see javax.servlet.ServletResponse#setContentType(java.lang.String) |
787 * @see javax.servlet.ServletResponse#setContentType(java.lang.String) | 787 */ |
788 */ | 788 public void setContentType(String contentType) |
789 public void setContentType(String contentType) | 789 { |
790 { | 790 if (isCommitted() || _connection.isIncluding()) |
791 if (isCommitted() || _connection.isIncluding()) | 791 return; |
792 return; | 792 |
793 | 793 // Yes this method is horribly complex.... but there are lots of special cases and |
794 // Yes this method is horribly complex.... but there are lots of special cases and | 794 // as this method is called on every request, it is worth trying to save string creation. |
795 // as this method is called on every request, it is worth trying to save string creation. | 795 // |
796 // | 796 |
797 | 797 if (contentType==null) |
798 if (contentType==null) | 798 { |
799 { | 799 if (_locale==null) |
800 if (_locale==null) | 800 _characterEncoding=null; |
801 _characterEncoding=null; | 801 _mimeType=null; |
802 _mimeType=null; | 802 _cachedMimeType=null; |
803 _cachedMimeType=null; | 803 _contentType=null; |
804 _contentType=null; | 804 _connection.getResponseFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER); |
805 _connection.getResponseFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER); | 805 } |
806 } | 806 else |
807 else | 807 { |
808 { | 808 // Look for encoding in contentType |
809 // Look for encoding in contentType | 809 int i0=contentType.indexOf(';'); |
810 int i0=contentType.indexOf(';'); | 810 |
811 | 811 if (i0>0) |
812 if (i0>0) | 812 { |
813 { | 813 // we have content type parameters |
814 // we have content type parameters | 814 |
815 | 815 // Extract params off mimetype |
816 // Extract params off mimetype | 816 _mimeType=contentType.substring(0,i0).trim(); |
817 _mimeType=contentType.substring(0,i0).trim(); | 817 _cachedMimeType=MimeTypes.CACHE.get(_mimeType); |
818 _cachedMimeType=MimeTypes.CACHE.get(_mimeType); | 818 |
819 | 819 // Look for charset |
820 // Look for charset | 820 int i1=contentType.indexOf("charset=",i0+1); |
821 int i1=contentType.indexOf("charset=",i0+1); | 821 if (i1>=0) |
822 if (i1>=0) | 822 { |
823 { | 823 _explicitEncoding=true; |
824 _explicitEncoding=true; | 824 int i8=i1+8; |
825 int i8=i1+8; | 825 int i2 = contentType.indexOf(' ',i8); |
826 int i2 = contentType.indexOf(' ',i8); | 826 |
827 | 827 if (_outputState==WRITER) |
828 if (_outputState==WRITER) | 828 { |
829 { | 829 // strip the charset and ignore; |
830 // strip the charset and ignore; | 830 if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' ')) |
831 if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' ')) | 831 { |
832 { | 832 if (_cachedMimeType!=null) |
833 if (_cachedMimeType!=null) | 833 { |
834 { | 834 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding); |
835 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding); | 835 if (content_type!=null) |
836 if (content_type!=null) | 836 { |
837 { | 837 _contentType=content_type.toString(); |
838 _contentType=content_type.toString(); | 838 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type); |
839 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type); | 839 } |
840 } | 840 else |
841 else | 841 { |
842 { | 842 _contentType=_mimeType+";charset="+_characterEncoding; |
843 _contentType=_mimeType+";charset="+_characterEncoding; | 843 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
844 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 844 } |
845 } | 845 } |
846 } | 846 else |
847 else | 847 { |
848 { | 848 _contentType=_mimeType+";charset="+_characterEncoding; |
849 _contentType=_mimeType+";charset="+_characterEncoding; | 849 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
850 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 850 } |
851 } | 851 } |
852 } | 852 else if (i2<0) |
853 else if (i2<0) | 853 { |
854 { | 854 _contentType=contentType.substring(0,i1)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); |
855 _contentType=contentType.substring(0,i1)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); | 855 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
856 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 856 } |
857 } | 857 else |
858 else | 858 { |
859 { | 859 _contentType=contentType.substring(0,i1)+contentType.substring(i2)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); |
860 _contentType=contentType.substring(0,i1)+contentType.substring(i2)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); | 860 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
861 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 861 } |
862 } | 862 } |
863 } | 863 else if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' ')) |
864 else if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' ')) | 864 { |
865 { | 865 // The params are just the char encoding |
866 // The params are just the char encoding | 866 _cachedMimeType=MimeTypes.CACHE.get(_mimeType); |
867 _cachedMimeType=MimeTypes.CACHE.get(_mimeType); | 867 _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8)); |
868 _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8)); | 868 |
869 | 869 if (_cachedMimeType!=null) |
870 if (_cachedMimeType!=null) | 870 { |
871 { | 871 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding); |
872 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding); | 872 if (content_type!=null) |
873 if (content_type!=null) | 873 { |
874 { | 874 _contentType=content_type.toString(); |
875 _contentType=content_type.toString(); | 875 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type); |
876 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type); | 876 } |
877 } | 877 else |
878 else | 878 { |
879 { | 879 _contentType=contentType; |
880 _contentType=contentType; | 880 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
881 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 881 } |
882 } | 882 } |
883 } | 883 else |
884 else | 884 { |
885 { | 885 _contentType=contentType; |
886 _contentType=contentType; | 886 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
887 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 887 } |
888 } | 888 } |
889 } | 889 else if (i2>0) |
890 else if (i2>0) | 890 { |
891 { | 891 _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8,i2)); |
892 _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8,i2)); | 892 _contentType=contentType; |
893 _contentType=contentType; | 893 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
894 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 894 } |
895 } | 895 else |
896 else | 896 { |
897 { | 897 _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8)); |
898 _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8)); | 898 _contentType=contentType; |
899 _contentType=contentType; | 899 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
900 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 900 } |
901 } | 901 } |
902 } | 902 else // No encoding in the params. |
903 else // No encoding in the params. | 903 { |
904 { | 904 _cachedMimeType=null; |
905 _cachedMimeType=null; | 905 _contentType=_characterEncoding==null?contentType:contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); |
906 _contentType=_characterEncoding==null?contentType:contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); | 906 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
907 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 907 } |
908 } | 908 } |
909 } | 909 else // No params at all |
910 else // No params at all | 910 { |
911 { | 911 _mimeType=contentType; |
912 _mimeType=contentType; | 912 _cachedMimeType=MimeTypes.CACHE.get(_mimeType); |
913 _cachedMimeType=MimeTypes.CACHE.get(_mimeType); | 913 |
914 | 914 if (_characterEncoding!=null) |
915 if (_characterEncoding!=null) | 915 { |
916 { | 916 if (_cachedMimeType!=null) |
917 if (_cachedMimeType!=null) | 917 { |
918 { | 918 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding); |
919 CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding); | 919 if (content_type!=null) |
920 if (content_type!=null) | 920 { |
921 { | 921 _contentType=content_type.toString(); |
922 _contentType=content_type.toString(); | 922 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type); |
923 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type); | 923 } |
924 } | 924 else |
925 else | 925 { |
926 { | 926 _contentType=_mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); |
927 _contentType=_mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); | 927 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
928 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 928 } |
929 } | 929 } |
930 } | 930 else |
931 else | 931 { |
932 { | 932 _contentType=contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); |
933 _contentType=contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= "); | 933 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
934 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 934 } |
935 } | 935 } |
936 } | 936 else if (_cachedMimeType!=null) |
937 else if (_cachedMimeType!=null) | 937 { |
938 { | 938 _contentType=_cachedMimeType.toString(); |
939 _contentType=_cachedMimeType.toString(); | 939 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_cachedMimeType); |
940 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_cachedMimeType); | 940 } |
941 } | 941 else |
942 else | 942 { |
943 { | 943 _contentType=contentType; |
944 _contentType=contentType; | 944 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
945 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 945 } |
946 } | 946 } |
947 } | 947 } |
948 } | 948 } |
949 } | 949 |
950 | 950 /* ------------------------------------------------------------ */ |
951 /* ------------------------------------------------------------ */ | 951 /* |
952 /* | 952 * @see javax.servlet.ServletResponse#setBufferSize(int) |
953 * @see javax.servlet.ServletResponse#setBufferSize(int) | 953 */ |
954 */ | 954 public void setBufferSize(int size) |
955 public void setBufferSize(int size) | 955 { |
956 { | 956 if (isCommitted() || getContentCount()>0) |
957 if (isCommitted() || getContentCount()>0) | 957 throw new IllegalStateException("Committed or content written"); |
958 throw new IllegalStateException("Committed or content written"); | 958 _connection.getGenerator().increaseContentBufferSize(size); |
959 _connection.getGenerator().increaseContentBufferSize(size); | 959 } |
960 } | 960 |
961 | 961 /* ------------------------------------------------------------ */ |
962 /* ------------------------------------------------------------ */ | 962 /* |
963 /* | 963 * @see javax.servlet.ServletResponse#getBufferSize() |
964 * @see javax.servlet.ServletResponse#getBufferSize() | 964 */ |
965 */ | 965 public int getBufferSize() |
966 public int getBufferSize() | 966 { |
967 { | 967 return _connection.getGenerator().getContentBufferSize(); |
968 return _connection.getGenerator().getContentBufferSize(); | 968 } |
969 } | 969 |
970 | 970 /* ------------------------------------------------------------ */ |
971 /* ------------------------------------------------------------ */ | 971 /* |
972 /* | 972 * @see javax.servlet.ServletResponse#flushBuffer() |
973 * @see javax.servlet.ServletResponse#flushBuffer() | 973 */ |
974 */ | 974 public void flushBuffer() throws IOException |
975 public void flushBuffer() throws IOException | 975 { |
976 { | 976 _connection.flushResponse(); |
977 _connection.flushResponse(); | 977 } |
978 } | 978 |
979 | 979 /* ------------------------------------------------------------ */ |
980 /* ------------------------------------------------------------ */ | 980 /* |
981 /* | 981 * @see javax.servlet.ServletResponse#reset() |
982 * @see javax.servlet.ServletResponse#reset() | 982 */ |
983 */ | 983 public void reset() |
984 public void reset() | 984 { |
985 { | 985 resetBuffer(); |
986 resetBuffer(); | 986 fwdReset(); |
987 fwdReset(); | 987 _status=200; |
988 _status=200; | 988 _reason=null; |
989 _reason=null; | 989 |
990 | 990 HttpFields response_fields=_connection.getResponseFields(); |
991 HttpFields response_fields=_connection.getResponseFields(); | 991 |
992 | 992 response_fields.clear(); |
993 response_fields.clear(); | 993 String connection=_connection.getRequestFields().getStringField(HttpHeaders.CONNECTION_BUFFER); |
994 String connection=_connection.getRequestFields().getStringField(HttpHeaders.CONNECTION_BUFFER); | 994 if (connection!=null) |
995 if (connection!=null) | 995 { |
996 { | 996 String[] values = connection.split(","); |
997 String[] values = connection.split(","); | 997 for (int i=0;values!=null && i<values.length;i++) |
998 for (int i=0;values!=null && i<values.length;i++) | 998 { |
999 { | 999 CachedBuffer cb = HttpHeaderValues.CACHE.get(values[0].trim()); |
1000 CachedBuffer cb = HttpHeaderValues.CACHE.get(values[0].trim()); | 1000 |
1001 | 1001 if (cb!=null) |
1002 if (cb!=null) | 1002 { |
1003 { | 1003 switch(cb.getOrdinal()) |
1004 switch(cb.getOrdinal()) | 1004 { |
1005 { | 1005 case HttpHeaderValues.CLOSE_ORDINAL: |
1006 case HttpHeaderValues.CLOSE_ORDINAL: | 1006 response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER); |
1007 response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER); | 1007 break; |
1008 break; | 1008 |
1009 | 1009 case HttpHeaderValues.KEEP_ALIVE_ORDINAL: |
1010 case HttpHeaderValues.KEEP_ALIVE_ORDINAL: | 1010 if (HttpVersions.HTTP_1_0.equalsIgnoreCase(_connection.getRequest().getProtocol())) |
1011 if (HttpVersions.HTTP_1_0.equalsIgnoreCase(_connection.getRequest().getProtocol())) | 1011 response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.KEEP_ALIVE); |
1012 response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.KEEP_ALIVE); | 1012 break; |
1013 break; | 1013 case HttpHeaderValues.TE_ORDINAL: |
1014 case HttpHeaderValues.TE_ORDINAL: | 1014 response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.TE); |
1015 response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.TE); | 1015 break; |
1016 break; | 1016 } |
1017 } | 1017 } |
1018 } | 1018 } |
1019 } | 1019 } |
1020 } | 1020 } |
1021 } | 1021 |
1022 | 1022 |
1023 | 1023 public void reset(boolean preserveCookies) |
1024 public void reset(boolean preserveCookies) | 1024 { |
1025 { | 1025 if (!preserveCookies) |
1026 if (!preserveCookies) | 1026 reset(); |
1027 reset(); | 1027 else |
1028 else | 1028 { |
1029 { | 1029 HttpFields response_fields=_connection.getResponseFields(); |
1030 HttpFields response_fields=_connection.getResponseFields(); | 1030 |
1031 | 1031 ArrayList<String> cookieValues = new ArrayList<String>(5); |
1032 ArrayList<String> cookieValues = new ArrayList<String>(5); | 1032 Enumeration<String> vals = response_fields.getValues(HttpHeaders.SET_COOKIE); |
1033 Enumeration<String> vals = response_fields.getValues(HttpHeaders.SET_COOKIE); | 1033 while (vals.hasMoreElements()) |
1034 while (vals.hasMoreElements()) | 1034 cookieValues.add((String)vals.nextElement()); |
1035 cookieValues.add((String)vals.nextElement()); | 1035 |
1036 | 1036 reset(); |
1037 reset(); | 1037 |
1038 | 1038 for (String v:cookieValues) |
1039 for (String v:cookieValues) | 1039 response_fields.add(HttpHeaders.SET_COOKIE, v); |
1040 response_fields.add(HttpHeaders.SET_COOKIE, v); | 1040 } |
1041 } | 1041 } |
1042 } | 1042 |
1043 | 1043 |
1044 | 1044 |
1045 | 1045 /* ------------------------------------------------------------ */ |
1046 /* ------------------------------------------------------------ */ | 1046 /* |
1047 /* | 1047 * @see javax.servlet.ServletResponse#reset() |
1048 * @see javax.servlet.ServletResponse#reset() | 1048 */ |
1049 */ | 1049 public void fwdReset() |
1050 public void fwdReset() | 1050 { |
1051 { | 1051 resetBuffer(); |
1052 resetBuffer(); | 1052 |
1053 | 1053 _writer=null; |
1054 _writer=null; | 1054 _outputState=NONE; |
1055 _outputState=NONE; | 1055 } |
1056 } | 1056 |
1057 | 1057 /* ------------------------------------------------------------ */ |
1058 /* ------------------------------------------------------------ */ | 1058 /* |
1059 /* | 1059 * @see javax.servlet.ServletResponse#resetBuffer() |
1060 * @see javax.servlet.ServletResponse#resetBuffer() | 1060 */ |
1061 */ | 1061 public void resetBuffer() |
1062 public void resetBuffer() | 1062 { |
1063 { | 1063 if (isCommitted()) |
1064 if (isCommitted()) | 1064 throw new IllegalStateException("Committed"); |
1065 throw new IllegalStateException("Committed"); | 1065 _connection.getGenerator().resetBuffer(); |
1066 _connection.getGenerator().resetBuffer(); | 1066 } |
1067 } | 1067 |
1068 | 1068 /* ------------------------------------------------------------ */ |
1069 /* ------------------------------------------------------------ */ | 1069 /* |
1070 /* | 1070 * @see javax.servlet.ServletResponse#isCommitted() |
1071 * @see javax.servlet.ServletResponse#isCommitted() | 1071 */ |
1072 */ | 1072 public boolean isCommitted() |
1073 public boolean isCommitted() | 1073 { |
1074 { | 1074 return _connection.isResponseCommitted(); |
1075 return _connection.isResponseCommitted(); | 1075 } |
1076 } | 1076 |
1077 | 1077 |
1078 | 1078 /* ------------------------------------------------------------ */ |
1079 /* ------------------------------------------------------------ */ | 1079 /* |
1080 /* | 1080 * @see javax.servlet.ServletResponse#setLocale(java.util.Locale) |
1081 * @see javax.servlet.ServletResponse#setLocale(java.util.Locale) | 1081 */ |
1082 */ | 1082 public void setLocale(Locale locale) |
1083 public void setLocale(Locale locale) | 1083 { |
1084 { | 1084 if (locale == null || isCommitted() ||_connection.isIncluding()) |
1085 if (locale == null || isCommitted() ||_connection.isIncluding()) | 1085 return; |
1086 return; | 1086 |
1087 | 1087 _locale = locale; |
1088 _locale = locale; | 1088 _connection.getResponseFields().put(HttpHeaders.CONTENT_LANGUAGE_BUFFER,locale.toString().replace('_','-')); |
1089 _connection.getResponseFields().put(HttpHeaders.CONTENT_LANGUAGE_BUFFER,locale.toString().replace('_','-')); | 1089 |
1090 | 1090 if (_explicitEncoding || _outputState!=0 ) |
1091 if (_explicitEncoding || _outputState!=0 ) | 1091 return; |
1092 return; | 1092 |
1093 | 1093 if (_connection.getRequest().getContext()==null) |
1094 if (_connection.getRequest().getContext()==null) | 1094 return; |
1095 return; | 1095 |
1096 | 1096 String charset = _connection.getRequest().getContext().getContextHandler().getLocaleEncoding(locale); |
1097 String charset = _connection.getRequest().getContext().getContextHandler().getLocaleEncoding(locale); | 1097 |
1098 | 1098 if (charset!=null && charset.length()>0) |
1099 if (charset!=null && charset.length()>0) | 1099 { |
1100 { | 1100 _characterEncoding=charset; |
1101 _characterEncoding=charset; | 1101 |
1102 | 1102 /* get current MIME type from Content-Type header */ |
1103 /* get current MIME type from Content-Type header */ | 1103 String type=getContentType(); |
1104 String type=getContentType(); | 1104 if (type!=null) |
1105 if (type!=null) | 1105 { |
1106 { | 1106 _characterEncoding=charset; |
1107 _characterEncoding=charset; | 1107 int semi=type.indexOf(';'); |
1108 int semi=type.indexOf(';'); | 1108 if (semi<0) |
1109 if (semi<0) | 1109 { |
1110 { | 1110 _mimeType=type; |
1111 _mimeType=type; | 1111 _contentType= type += ";charset="+charset; |
1112 _contentType= type += ";charset="+charset; | 1112 } |
1113 } | 1113 else |
1114 else | 1114 { |
1115 { | 1115 _mimeType=type.substring(0,semi); |
1116 _mimeType=type.substring(0,semi); | 1116 _contentType= _mimeType += ";charset="+charset; |
1117 _contentType= _mimeType += ";charset="+charset; | 1117 } |
1118 } | 1118 |
1119 | 1119 _cachedMimeType=MimeTypes.CACHE.get(_mimeType); |
1120 _cachedMimeType=MimeTypes.CACHE.get(_mimeType); | 1120 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); |
1121 _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType); | 1121 } |
1122 } | 1122 } |
1123 } | 1123 } |
1124 } | 1124 |
1125 | 1125 /* ------------------------------------------------------------ */ |
1126 /* ------------------------------------------------------------ */ | 1126 /* |
1127 /* | 1127 * @see javax.servlet.ServletResponse#getLocale() |
1128 * @see javax.servlet.ServletResponse#getLocale() | 1128 */ |
1129 */ | 1129 public Locale getLocale() |
1130 public Locale getLocale() | 1130 { |
1131 { | 1131 if (_locale==null) |
1132 if (_locale==null) | 1132 return Locale.getDefault(); |
1133 return Locale.getDefault(); | 1133 return _locale; |
1134 return _locale; | 1134 } |
1135 } | 1135 |
1136 | 1136 /* ------------------------------------------------------------ */ |
1137 /* ------------------------------------------------------------ */ | 1137 /** |
1138 /** | 1138 * @return The HTTP status code that has been set for this request. This will be <code>200<code> |
1139 * @return The HTTP status code that has been set for this request. This will be <code>200<code> | 1139 * ({@link HttpServletResponse#SC_OK}), unless explicitly set through one of the <code>setStatus</code> methods. |
1140 * ({@link HttpServletResponse#SC_OK}), unless explicitly set through one of the <code>setStatus</code> methods. | 1140 */ |
1141 */ | 1141 public int getStatus() |
1142 public int getStatus() | 1142 { |
1143 { | 1143 return _status; |
1144 return _status; | 1144 } |
1145 } | 1145 |
1146 | 1146 /* ------------------------------------------------------------ */ |
1147 /* ------------------------------------------------------------ */ | 1147 /** |
1148 /** | 1148 * @return The reason associated with the current {@link #getStatus() status}. This will be <code>null</code>, |
1149 * @return The reason associated with the current {@link #getStatus() status}. This will be <code>null</code>, | 1149 * unless one of the <code>setStatus</code> methods have been called. |
1150 * unless one of the <code>setStatus</code> methods have been called. | 1150 */ |
1151 */ | 1151 public String getReason() |
1152 public String getReason() | 1152 { |
1153 { | 1153 return _reason; |
1154 return _reason; | 1154 } |
1155 } | 1155 |
1156 | 1156 /* ------------------------------------------------------------ */ |
1157 /* ------------------------------------------------------------ */ | 1157 /** |
1158 /** | 1158 */ |
1159 */ | 1159 public void complete() |
1160 public void complete() | 1160 throws IOException |
1161 throws IOException | 1161 { |
1162 { | 1162 _connection.completeResponse(); |
1163 _connection.completeResponse(); | 1163 } |
1164 } | 1164 |
1165 | 1165 /* ------------------------------------------------------------- */ |
1166 /* ------------------------------------------------------------- */ | 1166 /** |
1167 /** | 1167 * @return the number of bytes actually written in response body |
1168 * @return the number of bytes actually written in response body | 1168 */ |
1169 */ | 1169 public long getContentCount() |
1170 public long getContentCount() | 1170 { |
1171 { | 1171 if (_connection==null || _connection.getGenerator()==null) |
1172 if (_connection==null || _connection.getGenerator()==null) | 1172 return -1; |
1173 return -1; | 1173 return _connection.getGenerator().getContentWritten(); |
1174 return _connection.getGenerator().getContentWritten(); | 1174 } |
1175 } | 1175 |
1176 | 1176 /* ------------------------------------------------------------ */ |
1177 /* ------------------------------------------------------------ */ | 1177 public HttpFields getHttpFields() |
1178 public HttpFields getHttpFields() | 1178 { |
1179 { | 1179 return _connection.getResponseFields(); |
1180 return _connection.getResponseFields(); | 1180 } |
1181 } | 1181 |
1182 | 1182 /* ------------------------------------------------------------ */ |
1183 /* ------------------------------------------------------------ */ | 1183 @Override |
1184 @Override | 1184 public String toString() |
1185 public String toString() | 1185 { |
1186 { | 1186 return "HTTP/1.1 "+_status+" "+ (_reason==null?"":_reason) +System.getProperty("line.separator")+ |
1187 return "HTTP/1.1 "+_status+" "+ (_reason==null?"":_reason) +System.getProperty("line.separator")+ | 1187 _connection.getResponseFields().toString(); |
1188 _connection.getResponseFields().toString(); | 1188 } |
1189 } | 1189 |
1190 | 1190 /* ------------------------------------------------------------ */ |
1191 /* ------------------------------------------------------------ */ | 1191 /* ------------------------------------------------------------ */ |
1192 /* ------------------------------------------------------------ */ | 1192 /* ------------------------------------------------------------ */ |
1193 /* ------------------------------------------------------------ */ | 1193 private static class NullOutput extends ServletOutputStream |
1194 private static class NullOutput extends ServletOutputStream | 1194 { |
1195 { | 1195 @Override |
1196 @Override | 1196 public void write(int b) throws IOException |
1197 public void write(int b) throws IOException | 1197 { |
1198 { | 1198 } |
1199 } | 1199 |
1200 | 1200 @Override |
1201 @Override | 1201 public void print(String s) throws IOException |
1202 public void print(String s) throws IOException | 1202 { |
1203 { | 1203 } |
1204 } | 1204 |
1205 | 1205 @Override |
1206 @Override | 1206 public void println(String s) throws IOException |
1207 public void println(String s) throws IOException | 1207 { |
1208 { | 1208 } |
1209 } | 1209 |
1210 | 1210 @Override |
1211 @Override | 1211 public void write(byte[] b, int off, int len) throws IOException |
1212 public void write(byte[] b, int off, int len) throws IOException | 1212 { |
1213 { | 1213 } |
1214 } | 1214 |
1215 | 1215 } |
1216 } | |
1217 | 1216 |
1218 } | 1217 } |