1 16 package org.mortbay.http.ajp; 17 18 import java.io.IOException ; 19 import java.io.OutputStream ; 20 import java.util.Enumeration ; 21 22 import org.apache.commons.logging.Log; 23 import org.mortbay.log.LogFactory; 24 import org.mortbay.http.BufferedOutputStream; 25 import org.mortbay.http.HttpMessage; 26 import org.mortbay.http.HttpResponse; 27 import org.mortbay.util.LogSupport; 28 29 36 public class AJP13OutputStream extends BufferedOutputStream 37 { 38 private static Log log=LogFactory.getLog(AJP13OutputStream.class); 39 40 private AJP13ResponsePacket _packet; 41 private boolean _complete; 42 private boolean _completed; 43 private boolean _persistent=true; 44 private AJP13ResponsePacket _ajpResponse; 45 46 47 AJP13OutputStream(OutputStream out, int bufferSize) 48 { 49 super(out,bufferSize,AJP13ResponsePacket.__DATA_HDR,AJP13ResponsePacket.__DATA_HDR,1); 50 setFixed(true); 51 _packet=new AJP13ResponsePacket(_buf); 52 _packet.prepare(); 53 54 setBypassBuffer(false); 55 setFixed(true); 56 57 _ajpResponse=new AJP13ResponsePacket(bufferSize); 58 _ajpResponse.prepare(); 59 } 60 61 62 public void writeHeader(HttpMessage httpMessage) throws IOException 63 { 64 HttpResponse response=(HttpResponse)httpMessage; 65 response.setState(HttpMessage.__MSG_SENDING); 66 67 _ajpResponse.resetData(); 68 _ajpResponse.addByte(AJP13ResponsePacket.__SEND_HEADERS); 69 _ajpResponse.addInt(response.getStatus()); 70 _ajpResponse.addString(response.getReason()); 71 72 int mark=_ajpResponse.getMark(); 73 _ajpResponse.addInt(0); 74 int nh=0; 75 Enumeration e1=response.getFieldNames(); 76 while (e1.hasMoreElements()) 77 { 78 String h=(String )e1.nextElement(); 79 Enumeration e2=response.getFieldValues(h); 80 while (e2.hasMoreElements()) 81 { 82 _ajpResponse.addHeader(h); 83 _ajpResponse.addString((String )e2.nextElement()); 84 nh++; 85 } 86 } 87 88 if (nh>0) 89 _ajpResponse.setInt(mark,nh); 90 _ajpResponse.setDataSize(); 91 92 write(_ajpResponse); 93 94 _ajpResponse.resetData(); 95 } 96 97 98 public void write(AJP13Packet packet) throws IOException 99 { 100 packet.write(_out); 101 } 102 103 104 public void flush() throws IOException 105 { 106 super.flush(); 107 if (_complete&&!_completed) 108 { 109 _completed=true; 110 111 _packet.resetData(); 112 _packet.addByte(AJP13ResponsePacket.__END_RESPONSE); 113 _packet.addBoolean(_persistent); 114 _packet.setDataSize(); 115 write(_packet); 116 _packet.resetData(); 117 } 118 } 119 120 121 public void close() throws IOException 122 { 123 _complete=true; 124 flush(); 125 } 126 127 128 public void resetStream() 129 { 130 _complete=false; 131 _completed=false; 132 super.resetStream(); 133 } 134 135 136 public void destroy() 137 { 138 if (_packet!=null) 139 _packet.destroy(); 140 _packet=null; 141 if (_ajpResponse!=null) 142 _ajpResponse.destroy(); 143 _ajpResponse=null; 144 _out=null; 145 } 146 147 148 public void end() throws IOException 149 { 150 _persistent=false; 151 } 152 153 154 protected void wrapBuffer() throws IOException 155 { 156 if (size()==0) 157 return; 158 159 if (_buf!=_packet.getBuffer()) 160 { 161 _packet=new AJP13ResponsePacket(_buf); 162 _packet.prepare(); 163 } 164 165 prewrite(_buf,0,AJP13ResponsePacket.__DATA_HDR); 166 _packet.resetData(); 167 _packet.addByte(AJP13ResponsePacket.__SEND_BODY_CHUNK); 168 _packet.setDataSize(size()-AJP13ResponsePacket.__HDR_SIZE); 169 postwrite((byte)0); 170 } 171 172 173 protected void bypassWrite(byte[] b, int offset, int length) throws IOException 174 { 175 log.warn(LogSupport.NOT_IMPLEMENTED); 176 } 177 178 179 180 public void writeTo(OutputStream out) throws IOException 181 { 182 int sz=size(); 183 184 if (sz<=AJP13ResponsePacket.__MAX_BUF) 185 super.writeTo(out); 186 else 187 { 188 int offset=preReserve(); 189 int data=sz-AJP13ResponsePacket.__DATA_HDR; 190 191 while (data>AJP13ResponsePacket.__MAX_DATA) 192 { 193 _packet.setDataSize(AJP13ResponsePacket.__MAX_BUF-AJP13ResponsePacket.__HDR_SIZE); 194 if (offset>0) 195 System.arraycopy(_buf,0,_buf,offset,AJP13ResponsePacket.__DATA_HDR); 196 out.write(_buf,offset,AJP13ResponsePacket.__MAX_BUF); 197 198 data-=AJP13ResponsePacket.__MAX_DATA; 199 offset+=AJP13ResponsePacket.__MAX_DATA; 200 } 201 202 int len=data+AJP13ResponsePacket.__DATA_HDR; 203 _packet.setDataSize(len-AJP13ResponsePacket.__HDR_SIZE); 204 if (offset>0) 205 System.arraycopy(_buf,0,_buf,offset,AJP13ResponsePacket.__DATA_HDR); 206 out.write(_buf,offset,len); 207 } 208 } 209 } 210 | Popular Tags |