1 16 package org.mortbay.http; 17 18 import java.io.IOException ; 19 import java.io.InputStream ; 20 import java.io.OutputStream ; 21 import java.io.StringWriter ; 22 import java.io.Writer ; 23 import java.util.Collections ; 24 import java.util.Date ; 25 import java.util.Enumeration ; 26 import java.util.HashMap ; 27 import java.util.List ; 28 import java.util.Map ; 29 30 import org.apache.commons.logging.Log; 31 import org.mortbay.log.LogFactory; 32 import org.mortbay.util.LogSupport; 33 import org.mortbay.util.QuotedStringTokenizer; 34 import org.mortbay.util.TypeUtil; 35 36 37 38 46 47 public abstract class HttpMessage 48 { 49 private static Log log = LogFactory.getLog(HttpMessage.class); 50 51 52 public final static String __SCHEME ="http"; 53 public final static String __SSL_SCHEME ="https"; 54 55 56 public final static String __HTTP_0_9 ="HTTP/0.9"; 57 public final static String __HTTP_1_0 ="HTTP/1.0"; 58 public final static String __HTTP_1_1 ="HTTP/1.1"; 59 public final static String __HTTP_1_X ="HTTP/1."; 60 61 62 public interface HeaderWriter 63 { 64 void writeHeader(HttpMessage httpMessage) 65 throws IOException ; 66 } 67 68 69 70 72 public final static int 73 __MSG_EDITABLE=0, __MSG_BAD=1, __MSG_RECEIVED=2, __MSG_SENDING=3, __MSG_SENT=4; 79 public final static String [] __state = 80 { 81 "EDITABLE", 82 "BAD", 83 "RECEIVED", 84 "SENDING", 85 "SENT" 86 }; 87 88 89 protected int _state=__MSG_EDITABLE; 90 protected String _version; 91 protected int _dotVersion; 92 protected HttpFields _header=new HttpFields(); 93 protected HttpConnection _connection; 94 protected String _characterEncoding; 95 protected String _mimeType; 96 protected Object _wrapper; 97 protected Map _attributes; 98 99 100 102 protected HttpMessage() 103 {} 104 105 106 108 protected HttpMessage(HttpConnection connection) 109 { 110 _connection=connection; 111 } 112 113 114 121 public void setWrapper(Object wrapper) 122 { 123 _wrapper=wrapper; 124 } 125 126 127 130 public Object getWrapper() 131 { 132 return _wrapper; 133 } 134 135 136 protected void reset() 137 { 138 _state=__MSG_EDITABLE; 139 _header.clear(); 140 } 141 142 143 public HttpConnection getHttpConnection() 144 { 145 return _connection; 146 } 147 148 149 public InputStream getInputStream() 150 { 151 if (_connection==null) 152 return null; 153 return _connection.getInputStream(); 154 } 155 156 157 public OutputStream getOutputStream() 158 { 159 if (_connection==null) 160 return null; 161 return _connection.getOutputStream(); 162 } 163 164 165 175 public int getState() 176 { 177 return _state; 178 } 179 180 181 187 public int setState(int state) 188 { 189 int last=_state; 190 _state=state; 191 return last; 192 } 193 194 195 196 199 public String getVersion() 200 { 201 return _version; 202 } 203 204 207 public int getDotVersion() 208 { 209 return _dotVersion; 210 } 211 212 213 216 public Enumeration getFieldNames() 217 { 218 return _header.getFieldNames(); 219 } 220 221 222 226 public boolean containsField(String name) 227 { 228 return _header.containsKey(name); 229 } 230 231 232 238 public String getField(String name) 239 { 240 return _header.get(name); 241 } 242 243 244 249 public Enumeration getFieldValues(String name) 250 { 251 return _header.getValues(name); 252 } 253 254 255 261 public Enumeration getFieldValues(String name,String separators) 262 { 263 return _header.getValues(name,separators); 264 } 265 266 267 268 276 public String setField(String name, String value) 277 { 278 if (_state!=__MSG_EDITABLE) 279 return null; 280 281 if (HttpFields.__ContentType.equalsIgnoreCase(name)) 282 { 283 String old=_header.get(name); 284 setContentType(value); 285 return old; 286 } 287 288 return _header.put(name,value); 289 } 290 291 292 299 public void setField(String name, List value) 300 { 301 if (_state!=__MSG_EDITABLE) 302 return; 303 _header.put(name,value); 304 } 305 306 307 316 public void addField(String name, String value) 317 throws IllegalStateException 318 { 319 if (_state!=__MSG_EDITABLE) 320 return; 321 _header.add(name,value); 322 } 323 324 325 331 public int getIntField(String name) 332 { 333 return _header.getIntField(name); 334 } 335 336 337 342 public void setIntField(String name, int value) 343 { 344 if (_state!=__MSG_EDITABLE) 345 return; 346 _header.put(name, TypeUtil.toString(value)); 347 } 348 349 350 355 public void addIntField(String name, int value) 356 { 357 if (_state!=__MSG_EDITABLE) 358 return; 359 _header.add(name, TypeUtil.toString(value)); 360 } 361 362 363 369 public long getDateField(String name) 370 { 371 return _header.getDateField(name); 372 } 373 374 375 376 381 public void setDateField(String name, Date date) 382 { 383 if (_state!=__MSG_EDITABLE) 384 return; 385 _header.putDateField(name,date); 386 } 387 388 389 394 public void addDateField(String name, Date date) 395 { 396 if (_state!=__MSG_EDITABLE) 397 return; 398 _header.addDateField(name,date); 399 } 400 401 402 407 public void setDateField(String name, long date) 408 { 409 if (_state!=__MSG_EDITABLE) 410 return; 411 _header.putDateField(name,date); 412 } 413 414 415 422 public void addDateField(String name, long date) 423 { 424 if (_state!=__MSG_EDITABLE) 425 return; 426 _header.addDateField(name,date); 427 } 428 429 430 431 438 public String removeField(String name) 439 throws IllegalStateException 440 { 441 if (_state!=__MSG_EDITABLE) 442 return null; 443 return _header.remove(name); 444 } 445 446 447 451 public void setVersion(String version) 452 { 453 if (_state!=__MSG_EDITABLE) 454 throw new IllegalStateException ("Not EDITABLE"); 455 if (version.equalsIgnoreCase(__HTTP_1_1)) 456 { 457 _dotVersion=1; 458 _version=__HTTP_1_1; 459 } 460 else if (version.equalsIgnoreCase(__HTTP_1_0)) 461 { 462 _dotVersion=0; 463 _version=__HTTP_1_0; 464 } 465 else if (version.equalsIgnoreCase(__HTTP_0_9)) 466 { 467 _dotVersion=-1; 468 _version=__HTTP_0_9; 469 } 470 else 471 throw new IllegalArgumentException ("Unknown version"); 472 } 473 474 475 478 public HttpFields getHeader() 479 { 480 if (_state!=__MSG_EDITABLE) 481 throw new IllegalStateException ("Can't get header in "+__state[_state]); 482 483 return _header; 484 } 485 486 487 488 public int getContentLength() 489 { 490 return getIntField(HttpFields.__ContentLength); 491 } 492 493 494 public void setContentLength(int len) 495 { 496 setIntField(HttpFields.__ContentLength,len); 497 } 498 499 500 505 public String getCharacterEncoding() 506 { 507 return _characterEncoding; 508 } 509 510 511 515 public void setCharacterEncoding(String encoding,boolean setField) 516 { 517 if (isCommitted()) 518 return; 519 520 if (encoding==null) 521 { 522 if (_characterEncoding!=null) 524 { 525 _characterEncoding=null; 526 if (setField) 527 _header.put(HttpFields.__ContentType,_mimeType); 528 } 529 } 530 else 531 { 532 _characterEncoding=encoding; 534 if (setField && _mimeType!=null) 535 { 536 _header.put(HttpFields.__ContentType, 537 _mimeType+";charset="+ 538 QuotedStringTokenizer.quote(_characterEncoding,";= ")); 539 } 540 } 541 } 542 543 544 public String getContentType() 545 { 546 return getField(HttpFields.__ContentType); 547 } 548 549 550 public void setContentType(String contentType) 551 { 552 if (isCommitted()) 553 return; 554 555 if (contentType==null) 556 { 557 _mimeType=null; 558 _header.remove(HttpFields.__ContentType); 559 } 560 else 561 { 562 int i0=contentType.indexOf(';'); 564 565 if (i0>0) 566 { 567 _mimeType=contentType.substring(0,i0).trim(); 569 570 int i1=contentType.indexOf("charset=",i0); 572 if (i1>=0) 573 { 574 i1+=8; 575 int i2 = contentType.indexOf(' ',i1); 576 _characterEncoding = (0<i2) 577 ? contentType.substring(i1,i2) 578 : contentType.substring(i1); 579 _characterEncoding = QuotedStringTokenizer.unquote(_characterEncoding); 580 } 581 else { 583 if (_characterEncoding!=null) 584 contentType+=";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= "); 586 } 587 } 588 else { 590 _mimeType=contentType; 591 if (_characterEncoding!=null) 593 contentType+=";charset="+QuotedStringTokenizer.quote(_characterEncoding,";= "); 594 } 595 596 _header.put(HttpFields.__ContentType,contentType); 597 } 598 } 599 600 601 public void updateMimeType() 602 { 603 _mimeType=null; 604 _characterEncoding=null; 605 606 String contentType= _header.get(HttpFields.__ContentType); 607 if (contentType!=null) 608 { 609 int i0=contentType.indexOf(';'); 611 612 if (i0>0) 613 { 614 _mimeType=contentType.substring(0,i0).trim(); 616 617 int i1=contentType.indexOf("charset=",i0); 619 if (i1>=0) 620 { 621 i1+=8; 622 int i2 = contentType.indexOf(' ',i1); 623 _characterEncoding = (0<i2) 624 ? contentType.substring(i1,i2) 625 : contentType.substring(i1); 626 _characterEncoding = QuotedStringTokenizer.unquote(_characterEncoding); 627 } 628 } 629 else 630 { 631 _mimeType=contentType; 632 } 633 } 634 } 635 636 637 641 public String getMimeType() 642 { 643 return _mimeType; 644 } 645 646 647 649 void recycle(HttpConnection connection) 650 { 651 _state=__MSG_EDITABLE; 652 _version=__HTTP_1_1; 653 _dotVersion=1; 654 _header.clear(); 655 _connection=connection; 656 _characterEncoding=null; 657 _mimeType=null; 658 if (_attributes!=null) 659 _attributes.clear(); 660 } 661 662 663 666 public void destroy() 667 { 668 recycle(null); 669 if (_header!=null) 670 _header.destroy(); 671 _header=null; 672 } 673 674 675 679 public synchronized String toString() 680 { 681 StringWriter writer = new StringWriter (); 682 683 int save_state=_state; 684 try{ 685 _state=__MSG_EDITABLE; 686 writeHeader(writer); 687 } 688 catch(IOException e) 689 { 690 log.warn(LogSupport.EXCEPTION,e); 691 } 692 finally 693 { 694 _state=save_state; 695 } 696 return writer.toString(); 697 } 698 699 700 701 704 abstract void writeHeader(Writer writer) 705 throws IOException ; 706 707 708 709 public boolean isCommitted() 710 { 711 return _state==__MSG_SENDING || _state==__MSG_SENT; 712 } 713 714 715 718 public boolean isDirty() 719 { 720 HttpOutputStream out=(HttpOutputStream)getOutputStream(); 721 return _state!=__MSG_EDITABLE || ( out!=null && out.isWritten()); 722 } 723 724 725 729 public Object getAttribute(String name) 730 { 731 if (_attributes==null) 732 return null; 733 return _attributes.get(name); 734 } 735 736 737 742 public Object setAttribute(String name, Object attribute) 743 { 744 if (_attributes==null) 745 _attributes=new HashMap (11); 746 return _attributes.put(name,attribute); 747 } 748 749 750 753 public Enumeration getAttributeNames() 754 { 755 if (_attributes==null) 756 return Collections.enumeration(Collections.EMPTY_LIST); 757 return Collections.enumeration(_attributes.keySet()); 758 } 759 760 761 764 public void removeAttribute(String name) 765 { 766 if (_attributes!=null) 767 _attributes.remove(name); 768 } 769 } 770 | Popular Tags |