1 16 package org.mortbay.jetty.servlet; 17 18 import java.io.IOException ; 19 import java.io.PrintWriter ; 20 import java.util.Locale ; 21 22 import javax.servlet.RequestDispatcher ; 23 import javax.servlet.ServletException ; 24 import javax.servlet.ServletOutputStream ; 25 import javax.servlet.ServletResponse ; 26 import javax.servlet.ServletResponseWrapper ; 27 import javax.servlet.http.Cookie ; 28 import javax.servlet.http.HttpServletResponse ; 29 import javax.servlet.http.HttpSession ; 30 31 import org.apache.commons.logging.Log; 32 import org.mortbay.log.LogFactory; 33 import org.mortbay.http.HttpContext; 34 import org.mortbay.http.HttpFields; 35 import org.mortbay.http.HttpOutputStream; 36 import org.mortbay.http.HttpResponse; 37 import org.mortbay.util.IO; 38 import org.mortbay.util.LogSupport; 39 import org.mortbay.util.StringUtil; 40 import org.mortbay.util.TypeUtil; 41 import org.mortbay.util.URI; 42 43 44 55 public class ServletHttpResponse implements HttpServletResponse 56 { 57 private static Log log = LogFactory.getLog(ServletHttpResponse.class); 58 59 public static final int 60 DISABLED=-1, 61 NO_OUT=0, 62 OUTPUTSTREAM_OUT=1, 63 WRITER_OUT=2; 64 65 private static ServletWriter __nullServletWriter; 66 private static ServletOut __nullServletOut; 67 static 68 { 69 try{ 70 __nullServletWriter = 71 new ServletWriter(IO.getNullStream()); 72 __nullServletOut = 73 new ServletOut(IO.getNullStream()); 74 } 75 catch (Exception e) 76 { 77 log.fatal(e); System.exit(1); 78 } 79 } 80 81 82 83 private HttpResponse _httpResponse; 84 private ServletHttpRequest _servletHttpRequest; 85 private int _outputState=NO_OUT; 86 private ServletOut _out =null; 87 private ServletWriter _writer=null; 88 private HttpSession _session=null; 89 private boolean _noSession=false; 90 private Locale _locale=null; 91 private boolean _charEncodingSetInContentType=false; 92 93 94 95 public ServletHttpResponse(ServletHttpRequest request,HttpResponse response) 96 { 97 _servletHttpRequest=request; 98 _servletHttpRequest.setServletHttpResponse(this); 99 _httpResponse=response; 100 } 101 102 103 void recycle() 104 { 105 _outputState=NO_OUT; 106 _out=null; 107 _writer=null; 108 _session=null; 109 _noSession=false; 110 _locale=null; 111 _charEncodingSetInContentType=false; 112 } 113 114 115 int getOutputState() 116 { 117 return _outputState; 118 } 119 120 121 void setOutputState(int s) 122 throws IOException 123 { 124 if (s<0) 125 { 126 _outputState=DISABLED; 127 if (_writer!=null) 128 _writer.disable(); 129 _writer=null; 130 if (_out!=null) 131 _out.disable(); 132 _out=null; 133 } 134 else 135 _outputState=s; 136 } 137 138 139 140 HttpResponse getHttpResponse() 141 { 142 return _httpResponse; 143 } 144 145 146 void commit() 147 throws IOException 148 { 149 if (_writer!=null && _writer.isWritten()) 150 _writer.flush(); 151 else 152 _httpResponse.commit(); 153 } 154 155 156 void complete() 157 throws IOException 158 { 159 _httpResponse.completing(); 160 commit(); 161 setOutputState(DISABLED); 162 } 163 164 165 public boolean isCommitted() 166 { 167 return _httpResponse.isCommitted(); 168 } 169 170 171 boolean isDirty() 172 { 173 return _httpResponse.isDirty(); 174 } 175 176 177 public void setBufferSize(int size) 178 { 179 HttpOutputStream out = (HttpOutputStream)_httpResponse.getOutputStream(); 180 if (out.isWritten() || _writer!=null && _writer.isWritten()) 181 throw new IllegalStateException ("Output written"); 182 out.setBufferSize(size); 183 } 184 185 186 public int getBufferSize() 187 { 188 return ((HttpOutputStream)_httpResponse.getOutputStream()).getBufferSize(); 189 } 190 191 192 public void flushBuffer() 193 throws IOException 194 { 195 if (((HttpOutputStream)_httpResponse.getOutputStream()).isClosed()) 196 return; 197 198 if (_writer!=null) 199 _writer.flush(); 200 if (_out!=null) 201 _out.flush(); 202 if (_writer==null && _out==null) 203 _httpResponse.getOutputStream().flush(); 204 if (!_httpResponse.isCommitted()) 205 _httpResponse.commit(); 206 } 207 208 209 public void resetBuffer() 210 { 211 if (isCommitted()) 212 throw new IllegalStateException ("Committed"); 213 214 ((HttpOutputStream)_httpResponse.getOutputStream()).resetBuffer(); 215 if (_writer!=null) _writer.reset(); 216 } 217 218 219 public void reset() 220 { 221 resetBuffer(); 222 _httpResponse.reset(); 223 } 224 225 226 235 public void setLocale(Locale locale) 236 { 237 if (locale == null || isCommitted()) 238 return; 239 240 _locale = locale; 241 setHeader(HttpFields.__ContentLanguage,locale.toString().replace('_','-')); 242 243 if (this._outputState==0) 244 { 245 246 String type=_httpResponse.getField(HttpFields.__ContentType); 247 if (type==null) 248 { 249 type="application/octet-stream"; 252 } 253 254 HttpContext httpContext=_servletHttpRequest.getServletHandler().getHttpContext(); 255 if (httpContext instanceof ServletHttpContext) 256 { 257 String charset = ((ServletHttpContext)httpContext).getLocaleEncoding(locale); 258 if (charset != null && charset.length()>0) 259 { 260 int semi=type.indexOf(';'); 261 if (semi<0) 262 type += "; charset="+charset; 263 else if (!_charEncodingSetInContentType) 264 type = type.substring(0,semi)+"; charset="+charset; 265 266 setHeader(HttpFields.__ContentType,type); 267 } 268 269 } 270 } 271 } 272 273 274 public Locale getLocale() 275 { 276 if (_locale==null) 277 return Locale.getDefault(); 278 return _locale; 279 } 280 281 282 public void addCookie(Cookie cookie) 283 { 284 _httpResponse.addSetCookie(cookie); 285 } 286 287 288 public boolean containsHeader(String name) 289 { 290 return _httpResponse.containsField(name); 291 } 292 293 294 public String encodeURL(String url) 295 { 296 if (_servletHttpRequest==null || 298 _servletHttpRequest.isRequestedSessionIdFromCookie() && 299 _servletHttpRequest.getServletHandler().isUsingCookies()) 300 return url; 301 302 if (_session==null && !_noSession) 304 { 305 _session=_servletHttpRequest.getSession(false); 306 _noSession=(_session==null); 307 } 308 309 if (_session == null || url==null) 311 return url; 312 313 String id = _session.getId(); 315 if (id == null) 316 return url; 317 318 321 int prefix=url.indexOf(SessionManager.__SessionUrlPrefix); 323 if (prefix!=-1) 324 { 325 int suffix=url.indexOf("?",prefix); 326 if (suffix<0) 327 suffix=url.indexOf("#",prefix); 328 329 if (suffix<=prefix) 330 return url.substring(0,prefix+SessionManager.__SessionUrlPrefix.length())+id; 331 return url.substring(0,prefix+SessionManager.__SessionUrlPrefix.length())+id+ 332 url.substring(suffix); 333 } 334 335 int suffix=url.indexOf('?'); 337 if (suffix<0) 338 suffix=url.indexOf('#'); 339 if (suffix<0) 340 return url+SessionManager.__SessionUrlPrefix+id; 341 return url.substring(0,suffix)+ 342 SessionManager.__SessionUrlPrefix+id+url.substring(suffix); 343 } 344 345 346 public String encodeRedirectURL(String url) 347 { 348 return encodeURL(url); 349 } 350 351 352 355 public String encodeUrl(String url) 356 { 357 return encodeURL(url); 358 } 359 360 361 365 public String encodeRedirectUrl(String url) 366 { 367 return encodeRedirectURL(url); 368 } 369 370 371 public void sendError(int status, String message) 372 throws IOException 373 { 374 String error_page = 376 _servletHttpRequest.getServletHandler().getErrorPage(status,_servletHttpRequest); 377 378 resetBuffer(); 379 380 if (error_page==null) 382 { 383 _httpResponse.sendError(status,message); 385 } 386 else 387 { 388 _httpResponse.setStatus(status,message); 389 390 if (message == null) 391 { 392 message= (String )HttpResponse.__statusMsg.get(TypeUtil.newInteger(status)); 393 if (message == null) 394 message= "" + status; 395 } 396 397 ServletHolder holder = _servletHttpRequest.getServletHolder(); 399 if (holder!=null) 400 _servletHttpRequest.setAttribute(ServletHandler.__J_S_ERROR_SERVLET_NAME, 401 holder.getName()); 402 _servletHttpRequest.setAttribute(ServletHandler.__J_S_ERROR_REQUEST_URI, 403 _servletHttpRequest.getRequestURI()); 404 _servletHttpRequest.setAttribute(ServletHandler.__J_S_ERROR_STATUS_CODE, 405 new Integer (status)); 406 _servletHttpRequest.setAttribute(ServletHandler.__J_S_ERROR_MESSAGE, 407 message); 408 409 RequestDispatcher dispatcher= 410 _servletHttpRequest.getServletHandler().getServletContext() 411 .getRequestDispatcher(error_page); 412 413 try 414 { 415 ((Dispatcher)dispatcher).error(_servletHttpRequest,this); 416 } 417 catch(ServletException e) 418 { 419 log.warn(LogSupport.EXCEPTION,e); 420 _httpResponse.sendError(status,message); 421 } 422 } 423 complete(); 424 } 425 426 427 public void sendError(int status) 428 throws IOException 429 { 430 sendError(status,null); 431 } 432 433 434 public void sendRedirect(String url) 435 throws IOException 436 { 437 if (url==null) 438 throw new IllegalArgumentException (); 439 440 if (!URI.hasScheme(url)) 441 { 442 StringBuffer buf = _servletHttpRequest.getHttpRequest().getRootURL(); 443 if (url.startsWith("/")) 444 buf.append(URI.canonicalPath(url)); 445 else 446 { 447 String path=_servletHttpRequest.getRequestURI(); 448 String parent=(path.endsWith("/"))?path:URI.parentPath(path); 449 url=URI.canonicalPath(URI.addPaths(parent,url)); 450 if (!url.startsWith("/")) 451 buf.append('/'); 452 buf.append(url); 453 } 454 455 url=buf.toString(); 456 } 457 458 resetBuffer(); 459 460 _httpResponse.setField(HttpFields.__Location,url); 461 _httpResponse.setStatus(HttpResponse.__302_Moved_Temporarily); 462 complete(); 463 } 464 465 466 public void setDateHeader(String name, long value) 467 { 468 try{_httpResponse.setDateField(name,value);} 469 catch(IllegalStateException e){LogSupport.ignore(log,e);} 470 } 471 472 473 public void setHeader(String name, String value) 474 { 475 try{_httpResponse.setField(name,value);} 476 catch(IllegalStateException e){LogSupport.ignore(log,e);} 477 } 478 479 480 public void setIntHeader(String name, int value) 481 { 482 try{_httpResponse.setIntField(name,value);} 483 catch(IllegalStateException e){LogSupport.ignore(log,e);} 484 } 485 486 487 public void addDateHeader(String name, long value) 488 { 489 try{_httpResponse.addDateField(name,value);} 490 catch(IllegalStateException e){LogSupport.ignore(log,e);} 491 } 492 493 494 public void addHeader(String name, String value) 495 { 496 try{_httpResponse.addField(name,value);} 497 catch(IllegalStateException e){LogSupport.ignore(log,e);} 498 } 499 500 501 502 public void addIntHeader(String name, int value) 503 { 504 try{_httpResponse.addIntField(name,value);} 505 catch(IllegalStateException e){LogSupport.ignore(log,e);} 506 } 507 508 509 public void setStatus(int status) 510 { 511 _httpResponse.setStatus(status); 512 } 513 514 515 526 public void setStatus(int status, String message) 527 { 528 setStatus(status); 529 _httpResponse.setReason(message); 530 } 531 532 533 534 public ServletOutputStream getOutputStream() 535 { 536 if (_outputState==DISABLED) 537 return __nullServletOut; 538 539 if (_outputState!=NO_OUT && _outputState!=OUTPUTSTREAM_OUT) 540 throw new IllegalStateException (); 541 542 if (_writer!=null) 543 { 544 _writer.flush(); 545 _writer.disable(); 546 _writer=null; 547 } 548 549 if (_out==null) 550 _out = new ServletOut(_servletHttpRequest.getHttpRequest() 551 .getOutputStream()); 552 _outputState=OUTPUTSTREAM_OUT; 553 return _out; 554 } 555 556 557 public PrintWriter getWriter() 558 throws java.io.IOException 559 { 560 if (_outputState==DISABLED) 561 return __nullServletWriter; 562 563 if (_outputState!=NO_OUT && _outputState!=WRITER_OUT) 564 throw new IllegalStateException (); 565 566 if (_out!=null) 568 _out.flush(); 569 570 571 if (_writer==null) 572 { 573 574 String encoding = _httpResponse.getCharacterEncoding(); 575 576 if (encoding==null) 577 { 578 if (_servletHttpRequest!=null) 579 { 580 581 String mimeType = _httpResponse.getMimeType(); 582 encoding = _servletHttpRequest.getServletHandler() 583 .getHttpContext().getEncodingByMimeType(mimeType); 584 } 585 if (encoding==null) 586 encoding = StringUtil.__ISO_8859_1; 587 _httpResponse.setCharacterEncoding(encoding,true); 588 } 589 590 591 _writer = new ServletWriter(_httpResponse.getOutputStream(), encoding); 592 } 593 _outputState=WRITER_OUT; 594 return _writer; 595 } 596 597 598 public void setContentLength(int len) 599 { 600 if (!isCommitted()) 604 setIntHeader(HttpFields.__ContentLength,len); 605 } 606 607 608 public String getContentType() 609 { 610 return _httpResponse.getContentType(); 611 } 612 613 614 public void setContentType(String contentType) 615 { 616 if (isCommitted() || contentType==null) 617 return; 618 619 int semi=contentType.indexOf(';'); 620 if (semi>0) 621 { 622 int charset0=contentType.indexOf("charset=",semi); 623 if (charset0>0) 624 { 625 if (_outputState==WRITER_OUT) 626 { 627 int charset1=contentType.indexOf(' ',charset0); 629 630 if ((charset0==semi+1 && charset1<0) || 631 (charset0==semi+2 && charset1<0 && contentType.charAt(semi+1)==' ' )) 632 _httpResponse.setContentType(contentType.substring(0,semi)); 633 else if (charset1<0) 634 _httpResponse.setContentType(contentType.substring(0, charset0).trim()); 635 else 636 _httpResponse.setContentType(contentType.substring(0, charset0)+contentType.substring(charset1)); 637 } 638 else 639 { 640 _charEncodingSetInContentType=true; 641 _httpResponse.setContentType(contentType); 642 } 643 } 644 else 645 _httpResponse.setContentType(contentType); 646 } 647 else 648 _httpResponse.setContentType(contentType); 649 650 if (_locale!=null) 651 setLocale(_locale); 652 } 653 654 655 public void setCharacterEncoding(String encoding) 656 { 657 if (this._outputState==0 && !isCommitted()) 658 { 659 _charEncodingSetInContentType=true; 660 _httpResponse.setCharacterEncoding(encoding,true); 661 } 662 } 663 664 665 public String getCharacterEncoding() 666 { 667 String encoding=_httpResponse.getCharacterEncoding(); 668 return (encoding==null)?StringUtil.__ISO_8859_1:encoding; 669 } 670 671 672 public String toString() 673 { 674 return _httpResponse.toString(); 675 } 676 677 678 679 687 public static ServletHttpResponse unwrap(ServletResponse response) 688 { 689 while (!(response instanceof ServletHttpResponse)) 690 { 691 if (response instanceof ServletResponseWrapper ) 692 { 693 ServletResponseWrapper wrapper = 694 (ServletResponseWrapper )response; 695 response=wrapper.getResponse(); 696 } 697 else 698 throw new IllegalArgumentException ("Does not wrap ServletHttpResponse"); 699 } 700 701 return (ServletHttpResponse)response; 702 } 703 704 705 } 706 | Popular Tags |