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, "&", "&amp;");
271 message= StringUtil.replace(message, "&", "&amp;"); 271 message= StringUtil.replace(message, "<", "&lt;");
272 message= StringUtil.replace(message, "<", "&lt;"); 272 message= StringUtil.replace(message, ">", "&gt;");
273 message= StringUtil.replace(message, ">", "&gt;"); 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, "&", "&amp;");
278 uri= StringUtil.replace(uri, "&", "&amp;"); 278 uri= StringUtil.replace(uri, "<", "&lt;");
279 uri= StringUtil.replace(uri, "<", "&lt;"); 279 uri= StringUtil.replace(uri, ">", "&gt;");
280 uri= StringUtil.replace(uri, ">", "&gt;"); 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 }